Cele mai bune solutii
pentru problema "Critici"
(ziua2, problema3)
Punctaj Maxim : 75 puncte
Solutii :
Podeanu Dan - Bucuresti - 75 puncte
Dumitrescu Bogdan - Prahova - 55 puncte
Nicolescu Mihai - Brasov - 55 puncte
Comisia Centrala
Fisierele de teste
Program realizat de elevul Podeanu Dan - rezultat final : premiu II - 112 puncte
{$A+,B-,D+,E+,F-,G+,I+,L+,N+,O-,P-,Q-,R-,S+,T-,V+,X+,Y+} {$M 65520,0,655360} type critic = array[0..20] of byte; critic_list = array[1..100] of critic; adiacenta = array[1..100, 1..100] of byte; big_adiacenta = array[1..102, 1..102] of byte; var c, r: byte; cl: critic_list; a: adiacenta; b, b2: big_adiacenta; s, t: byte; n: byte; procedure InitData; begin fillchar(cl, sizeof(cl), 0); fillchar(a, sizeof(a), 0); end; procedure ReadData; var fin: text; i: integer; begin assign(fin, 'CRITICI.IN'); reset(fin); read(fin, c); readln(fin, r); for i := 1 to c do begin cl[i][0] := 0; while(not(eoln(fin))) do begin inc(cl[i][0]); read(fin, cl[i][cl[i][0]]); end; readln(fin); end; close(fin); end; function QueryMatch(x, y: byte): boolean; type hash = array[1..20] of byte; var ii: byte; diffs: integer; v1, v2: critic; h: hash; function GetMin(first, second: byte): byte; begin if(first < second) then GetMin := first else GetMin := second; end; begin if(abs(cl[x][0] - cl[y][0]) <> 1) then begin QueryMatch := false; exit; end; ii := 1; diffs := 0; fillchar(h, sizeof(h), 0); if(cl[x][0] < cl[y][0]) then begin v1 := cl[x]; v2 := cl[y]; end else begin v1 := cl[y]; v2 := cl[x]; end; for ii := 1 to v1[0] do h[v1[ii]] := 1; for ii := 1 to v2[0] do if(h[v2[ii]] = 0) then inc(diffs); if(diffs = 1) then QueryMatch := true else QueryMatch := false; end; procedure MakeAdiacenta; var i, j: integer; begin for i := 1 to c do for j := (i + 1) to c do if(QueryMatch(i, j)) then begin a[i, j] := 1; a[j, i] := 1; end else begin a[i, j] := 0; a[j, i] := 0; end; end; function GetPos(x: byte): byte; begin GetPos := x + 1; end; function GetS: byte; begin GetS := 1; end; function GetT: byte; begin GetT := c + 2; end; procedure MakeFluxInitialData; var i, j: integer; begin for i := 1 to c do begin for j := (i + 1) to c do if(a[i, j] = 1) then begin { writeln(i, ' ', j);} if((cl[i][0] mod 2) = 1) then b[GetPos(i), GetPos(j)] := 1 else b[GetPos(j), GetPos(i)] := 1; end; if((cl[i][0] mod 2) = 1) then b[GetS, GetPos(i)] := 1 else b[GetPos(i), GetT] := 1; end; end; { ######### FLUX ######### } procedure FluxIt; type reached_set = set of byte; path_array = array[1..256] of byte; var reached: reached_set; path: path_array; atpath: integer; FindT: boolean; i: integer; min: integer; procedure Way(from: byte; at: byte); var i: integer; begin path[at] := from; reached := reached + [from]; if(from = t) then begin FindT := true; atpath := at; exit; end; for i := 1 to n do if((b[from, i] = 1) and not(i in reached) and not(FindT)) then Way(i, at + 1); end; begin repeat atpath := 0; reached := []; FindT := false; Way(s, atpath + 1); if(FindT) then begin min := 32767; for i := 1 to atpath - 1 do if(b[path[i], path[i + 1]] < min) then min := b[path[i], path[i + 1]]; if(min = 32767) then begin writeln('Error: invalid min at flux.'); halt; end; for i := 1 to atpath - 1 do begin dec(b[path[i], path[i + 1]], min); inc(b[path[i + 1], path[i]], min); end; end; until(not(FindT)); end; { ######### WRITE RESULT ######### } procedure WriteResult; var i, j: integer; fout: text; count: integer; begin assign(fout, 'CRITICI.OUT'); rewrite(fout); count := 0; for i := GetPos(1) to GetPos(c) do for j := GetPos(1) to GetPos(c) do if(b[i, j] - b2[i, j] = -1) then inc(count); writeln(fout, count); for i := GetPos(1) to GetPos(c) do for j := GetPos(1) to GetPos(c) do if(b[i, j] - b2[i, j] = -1) then writeln(fout, i - 1, ' ', j - 1); close(fout); end; begin InitData; ReadData; MakeAdiacenta; fillchar(b, sizeof(b), 0); fillchar(b2, sizeof(b2), 0); MakeFluxInitialData; b2 := b; s := GetS; t := GetT; n := c + 2; FluxIt; WriteResult; end.
Program realizat de Comisia Centrala a Olimpiadei Nationale de Informatica
Fisierele de teste :