Cele mai bune solutii
pentru problema "Excel"
(ziua1, problema2)
Punctaj Maxim : 50 puncte
Solutii :
Erzse Gabriel - Bihor - 45 puncte
Caloian ciprian - Neamt - 35 puncte;
Comisia Centrala
Fisierele de teste
Program realizat de elevul Erzse Gabriel- rezultat final : premiu I - 195 puncte
{$A+,B-,D+,E+,F-,G+,I-,L+,N+,O-,P-,Q-,R-,S-,T-,V+,X+,Y+} {$M 65520,0,655360} program SpreadSheat; uses Crt; const NumeIn='EXCEL.IN'; NumeOut='EXCEL.OUT'; type MyType=(numar,adresa,oper); PNod=^Nod; Nod=record tip:MyType; nr:Longint; C,L:Char; Op:Char; st,dr:PNod; end; Mat=array['0'..'9','A'..'Z'] of PNod; var A:Mat; poz,N,M:Integer; ch,NC,MC:Char; fi,fo:Text; s:string; SePoate:Boolean; procedure expr(var p:PNod);forward; procedure fact(var p:PNod); var c1,c2:char; ss:string[15]; cod:integer; begin Inc(poz); if s[poz]='(' then begin expr(p); Inc(poz); end else if s[poz] in ['A'..'Z'] then begin c1:=s[poz]; Inc(poz); c2:=s[poz]; new(p); p^.dr:=nil; p^.st:=nil; p^.tip:=adresa; p^.L:=c2; p^.C:=c1; end else begin FillChar(ss,SizeOf(ss),0); ss:=ss+s[poz]; Inc(poz); while s[poz] in ['0'..'9'] do begin ss:=ss+s[poz]; Inc(poz); end; Dec(poz); new(p); p^.st:=nil; p^.dr:=nil; p^.tip:=numar; val(ss,p^.nr,cod); end; end; procedure termen(var p:PNod); var q:PNod; begin fact(p); while s[Poz+1] in ['*','/'] do begin New(q); q^.st:=p; q^.Op:=s[Poz+1]; q^.tip:=oper; Inc(poz); fact(q^.dr); p:=q; end; end; procedure expr(var p:Pnod); var q:PNod; begin termen(p); while s[Poz+1] in ['+','-'] do begin New(q); q^.st:=p; q^.Op:=s[Poz+1]; q^.tip:=oper; Inc(poz); termen(q^.dr); p:=q; end; end; procedure parc(p:PNod); begin if p=Nil then exit; parc(p^.st); case p^.tip of numar:write(p^.nr); adresa:write(p^.C,p^.L); oper:Write(p^.Op); end; parc(p^.dr); end; procedure CreeazaExpr(x,y:Integer); begin poz:=0; expr(A[Chr(x+Ord('0')-1),Chr(y+Ord('A')-1)]); end; procedure Scr; var i,j:Char; begin for i:='0' to NC do begin for j:='A' to MC do begin { WriteLn('[');} textcolor(white); parc(A[i,j]); Write(' ',Ord(A[i,j]^.tip),' '); textcolor(lightgray); { writeln; writeln(']'); if readkey=#27 then Halt;} end; writeln; end; writeln; ReadKey; end; procedure CitesteDate; var i,j:Integer; begin Assign(fi,NumeIn); Reset(fi); ReadLn(fi,N,M); NC:=Chr(N+Ord('0')-1); MC:=Chr(M+Ord('A')-1); for i:=1 to N do for j:=1 to M do begin FillChar(s,SizeOf(s),0); ReadLn(fi,s); CreeazaExpr(i,j); end; Close(fi); end; function OK(P:PNod):Boolean; var b1,b2:Boolean; begin if (p^.tip=numar) then OK:=True else if p^.tip=adresa then OK:=False else begin b1:=OK(p^.st); b2:=OK(p^.dr); if not(b1) or not(b2) then OK:=False else OK:=True; end; end; function Gasit:Boolean; var i,j:Char; begin for i:='0' to NC do for j:='A' to MC do if not(OK(A[i,j])) then begin Gasit:=False; Exit; end; Gasit:=True; end; function Eval(p:PNod):Longint; var x1,x2:Longint; begin if p^.tip=numar then Eval:=p^.nr else begin x1:=Eval(p^.st); x2:=Eval(p^.dr); case p^.op of '+':Eval:=x1+x2; '-':Eval:=x1-x2; '*':Eval:=x1*x2; '/':if x2<>0 then Eval:=x1 div x2 else begin WriteLn('Eroare: impartire la 0'); Write(fo,'EVALUARE IMPOSIBILA'); Close(fo); Halt; end; end; end; end; procedure Reducere(p:PNod); begin if p=nil then Exit; Reducere(p^.st); Reducere(p^.dr); if (p^.tip=adresa) then if (A[p^.L,p^.C]^.tip=numar) then begin { WriteLn(p^.L,p^.C); Scr;} p^.tip:=numar; p^.nr:=A[p^.L,p^.C]^.nr; SePoate:=True; end else if (A[p^.L,p^.C]^.tip=oper) and OK(A[p^.L,p^.C]) then BEGIN p^.tip:=numar; p^.nr:=Eval(A[p^.L,p^.C]); SePoate:=True; END; end; procedure Calculeaza; var i,j:Char; begin repeat { Scr;} SePoate:=False; for i:='0' to NC do for j:='A' to MC do begin Reducere(A[i,j]); end; until not(SePoate) or Gasit; { Scr;} end; procedure ScrieSol; var i,j:Char; begin if SePoate then begin for i:='0' to NC do begin for j:='A' to MC do begin Write(fo,Eval(A[i,j])); if j<MC then Write(fo,' '); end; if i<NC then WriteLn(fo); end; end else Write(fo,'EVALUARE IMPOSIBILA'); Close(fo); end; begin ClrScr; Assign(fo,NumeOut); Rewrite(fo); CitesteDate; Calculeaza; ScrieSol; end.
Program realizat de Comisia Centrala a Olimpiadei Nationale de Informatica
{$A+,B-,D+,E+,F-,G+,I+,L+,N+,O-,P-,Q-,R+,S+,T-,V+,X+,Y+} {$m 60000,0,655360} program Excel; const NrMaxLin = 10; LgMax = 100; type Linie = 0 .. NrMaxLin; Coloana = 'A' .. 'Z'; Expresie = string[LgMax]; Celula = record data: Expresie; v: longint; x: byte; end; Foaie = array [Linie, Coloana] of Celula; var F: Foaie; n, l: Linie; m, i: byte; cm, c: char; fout: text; numeout: string; procedure Citire; var fin: text; nume: string; l: Linie; c: char; begin write ('fisier intrare '); readln (nume); assign (fin, nume); reset (fin); readln (fin, n, m); cm := chr (ord ('A') + m - 1); for l := 0 to n-1 do for c := 'A' to cm do readln (fin, F[l, c].data); close (fin); end; procedure Afisare; var l: Linie; c: char; begin for l := 0 to n-1 do begin for c := 'A' to cm do write (fout, F[l, c].v:11); writeln (fout); end; close (fout); end; function EvaluareExpresie (var e: Expresie; var i: byte): longint; forward; function EvaluareFactor (var e: Expresie; var i: byte): longint; var ll: Linie; cc: char; ii: byte; cod: integer; v: longint; begin if e[i] = '(' then {verific daca factorul este o expresie intre paranteze} begin i := i + 1; {trec peste')'} EvaluareFactor := EvaluareExpresie (e, i); {evaluez expresia dintre paranteze} i := i + 1; {trec peste ')'} end else {factorul este un operand} if e[i] in ['A' .. 'Z'] then {factorul este o referinta de celula} begin ll := ord (e[i+1]) - ord ('0'); cc := e[i]; if F[ll, cc].x = 2 then EvaluareFactor := F[ll, cc].v else if F[ll, cc].x = 1 then begin writeln (fout, 'EVALUARE IMPOSIBILA'); close (fout); halt; end else begin ii := 1; EvaluareFactor := EvaluareExpresie(F[ll, cc].data, ii); end; inc (i, 2); end else {factorul este o valoare intreaga} begin ii := i + 1; while (ii <= length (e)) and (e[ii] in ['0' ..'9']) do inc (ii); val (copy (e, i, ii - i), v, cod); EvaluareFactor := v; i := ii; end end; function EvaluareTermen (var e: Expresie; var i: byte): longint; var f: longint; op: char; begin f := EvaluareFactor (e, i); {evaluez primul factor din care este constituit termenul}; while (i <= length (e)) and (e[i] in ['*', '/']) do {mai urmeaza factori} begin op := e[i]; i := i + 1; {trec peste '*'} if op = '*' then f := f * EvaluareFactor (e, i) else f := f div EvaluareFactor (e, i); end; EvaluareTermen := f end; function EvaluareExpresie (var e: Expresie; var i: byte): longint; var t: longint; op: char; begin t := EvaluareTermen (e, i); {evaluez primul termen din expresie} while (i < length (e)) and (e[i] in ['+', '-']) do {mai urmeaza termeni} begin op := e[i]; i := i + 1; {trec peste operator} if op = '+' then t := t + EvaluareTermen (e, i) else t := t - EvaluareTermen (e, i) end; EvaluareExpresie := t end; begin {program principal} Citire; write ('Fisier iesire '); readln (numeout); assign (fout, numeout); rewrite (fout); for l := 0 to n-1 do for c := 'A' to cm do if F[l, c].x = 0 then begin F[l, c].x := 1; i := 1; F[l, c].v := EvaluareExpresie (F[l, c].data, i); F[l, c].x := 2; end; Afisare; end.
Fisierele de teste :
Test 1 :
1 1
((1+2+3*(1+2+3)*(1+2*3*4*5)/2+4))
Test 2 :
2 1
1
-2*A0+30+A0*(A0+1)/2
Test 3 :
1 2
1000000000
A0/((1+4+5-50+60-10))+A0
Test 4 :
5 4
(B0+C1-1)/2
A2+C2-B3+10-5
1
2
A3*B1*20/100
-10
2*(C2+1)*(B3-1)+A1-100
0
10
(D4-A3)
3
0
1
B2+1
1000000
500
-10000
-10*3
0
D3/A2
Test 5 :
5 4
(B0+C1-1)/2
A2+C2-B3+10-5
1
2
A3*B1*20/100
-10
2*(C2+1)*(B3-1)+A1-100
0
10
(D4-A3)
3
0
1
B2+1
1000000
500-A0
-10000
-10*3
0
D3/A2
Test 6 :
10 20
A3+C3+1
C0*2
O3+1
C0-D3
1
E2-E3
10
-10
-10000000
2*3*4*5*6/1000
0
L1*L2/2
-1
-200
0
-5
-901
R2+R3-100
0
0
10-K1/2
100
11/2/3*4
0
1+F0*2
A0+B0-D0*10
H1*2
I1-1
A1+2-10
97
L1-10/2/3
M1-10+50
N1*2*(-1)
O1*2
B1/10
0
0
20
0
0
0
0
0
0
0
0
((G0-G7)*2)/2
5
0
0
0
0
0
0
G3-10*(1+2*(3*4-5))*(-30+50-70)/(10-8)
0
0
R4-R5+1
0
0
G0/O1*2
1
O2+2
D4-5
10
1
E1-G2+10
1
1
1
1
1
1
1
1
1
1
-2
1
1
2
2
2
D5*(-2)
R0+R1-10
2
2
2
2
2
2
2
2
2
2
2
2
R6-R7
2
2
0
10
10
(E1+E2-E3)*(E4-E5)/2
20
10
10
10
10
10
10
10
10
10
10
10
10
7
10
10
400
400
-3
400
E4/3
400
400
400
400
400
400
400
-5
400
400
400
400
400
-10
400
-100
-100
30
E7-L7+F7+5
1000
O7-N7
G8-100
-100
50
-100
A8/10
A8-I7
40
-30
P7/6
L7+K7-20
-100
20
S6-10
-100
B8-C8+(D8-E8)*(F8-M8+1)
200
C6+C7
10
E6-E7
20
H0-H2
300
300
300
300
300
2+M6-M7
300
300
300
300
300
10
300
0
31
21
B9-C9
0
0
0
0
0
0
0
0
0
0
0
0
0
0
S8/S7
0
Test 7 :
10 20
A3+C3+1
C0*2
O3+1
C0-D3
1
E2-E3
10
-10
-10000000
2*3*4*5*6/1000
0
L1/L2/2
-1
-200
0
-5
-901
R2+R3-100
0
0
10-K1/2
1-F1
11/2/3*4
0
1+F0*2
A0+B0-D0*10
H1*2
I1-1
A1+2-10
97
L1-10/2/3
M1-10+50
N1*2*(-1)
O1*2
B1/10
0
0
20
0
0
0
0
0
0
0
0
((G0-G7)*2)/2
5+G1
0
0
0
0
0
0
G3-10*(1+2*(3*4-5))*(-30+50-70)/(10-8)
0
0
R4-R5+1
0
0
G0/O1*2
1
O2+2
D4-5
10
1
E1-G2+10
1
1
1
1
1
1
1
1
1
1
-2
1
1
2
2
2
D5*(-2)
R0+R1-10
2
2
2
2
2
2
2
2
2
2
2
2
R6-R7
2
2
0
10
10
(E1+E2-E3)*(E4-E5)/2
20
10
10
10
10
10
10
10
10
10
10
10
10
7
10
10
400
400
-3
400
E4/3
400
400
400
400
400
400
400
-5
400
400
400
400
400
-10
400
-100
-100
30
E7-L7+F7+5
1000
O7-N7
G8-100
-100
50
-100
A8/10
A8-I7
40
-30
P7/6
L7+K7-20
-100
20
S6-10
-100
B8-C8+(D8-E8)*(F8-M8+1)
200
C6+C7
10
E6-E7
20
H0-H2
300
300
300
300
300
2+M6-M7
300
300
300
300
300
10
300
0
31
21
B9-C9
0
0
0
0
0
0
0
0
0
0
0
0
0
0
S8/S7
0
Test 8 :
10 26
B0+1
C0+1
D0+1
E0+1
F0+1
G0+1
H0+1
I0+1
J0+1
K0+1
L0+1
M0+1
N0+1
O0+1
P0+1
Q0+1
R0+1
S0+1
T0+1
U0+1
V0+1
W0+1
X0+1
Y0+1
Z0+1
A1+1
B1+1
C1+1
D1+1
E1+1
F1+1
G1+1
H1+1
I1+1
J1+1
K1+1
L1+1
M1+1
N1+1
O1+1
P1+1
Q1+1
R1+1
S1+1
T1+1
U1+1
V1+1
W1+1
X1+1
Y1+1
Z1+1
A2+1
B2+1
C2+1
D2+1
E2+1
F2+1
G2+1
H2+1
I2+1
J2+1
K2+1
L2+1
M2+1
N2+1
O2+1
P2+1
Q2+1
R2+1
S2+1
T2+1
U2+1
V2+1
W2+1
X2+1
Y2+1
Z2+1
A3+1
B3+1
C3+1
D3+1
E3+1
F3+1
G3+1
H3+1
I3+1
J3+1
K3+1
L3+1
M3+1
N3+1
O3+1
P3+1
Q3+1
R3+1
S3+1
T3+1
U3+1
V3+1
W3+1
X3+1
Y3+1
Z3+1
A4+1
B4+1
C4+1
D4+1
E4+1
F4+1
G4+1
H4+1
I4+1
J4+1
K4+1
L4+1
M4+1
N4+1
O4+1
P4+1
Q4+1
R4+1
S4+1
T4+1
U4+1
V4+1
W4+1
X4+1
Y4+1
Z4+1
A5+1
B5+1
C5+1
D5+1
E5+1
F5+1
G5+1
H5+1
I5+1
J5+1
K5+1
L5+1
M5+1
N5+1
O5+1
P5+1
Q5+1
R5+1
S5+1
T5+1
U5+1
V5+1
W5+1
X5+1
Y5+1
Z5+1
A6+1
B6+1
C6+1
D6+1
E6+1
F6+1
G6+1
H6+1
I6+1
J6+1
K6+1
L6+1
M6+1
N6+1
O6+1
P6+1
Q6+1
R6+1
S6+1
T6+1
U6+1
V6+1
W6+1
X6+1
Y6+1
Z6+1
A7+1
B7+1
C7+1
D7+1
E7+1
F7+1
G7+1
H7+1
I7+1
J7+1
K7+1
L7+1
M7+1
N7+1
O7+1
P7+1
Q7+1
R7+1
S7+1
T7+1
U7+1
V7+1
W7+1
X7+1
Y7+1
Z7+1
A8+1
B8+1
C8+1
D8+1
E8+1
F8+1
G8+1
H8+1
I8+1
J8+1
K8+1
L8+1
M8+1
N8+1
O8+1
P8+1
Q8+1
R8+1
S8+1
T8+1
U8+1
V8+1
W8+1
X8+1
Y8+1
Z8+1
A9+1
B9+1
C9+1
D9+1
E9+1
F9+1
G9+1
H9+1
I9+1
J9+1
K9+1
L9+1
M9+1
N9+1
O9+1
P9+1
Q9+1
R9+1
S9+1
T9+1
U9+1
V9+1
W9+1
X9+1
Y9+1
Z9+1
1
Test 9 :
10 26
B0+1
C0+1
D0+1
E0+1
F0+1
G0+1
H0+1
I0+1
J0+1
K0+1
L0+1
M0+1
N0+1
O0+1
P0+1
Q0+1
R0+1
S0+1
T0+1
U0+1
V0+1
W0+1
X0+1
Y0+1
Z0+1
A1+1
B1+1
C1+1
D1+1
E1+1
F1+1
G1+1
H1+1
I1+1
J1+1
K1+1
L1+1
M1+1
N1+1
O1+1
P1+1
Q1+1
R1+1
S1+1
T1+1
U1+1
V1+1
W1+1
X1+1
Y1+1
Z1+1
A2+1
B2+1
C2+1
D2+1
E2+1
F2+1
G2+1
H2+1
I2+1
J2+1
K2+1
L2+1
M2+1
N2+1
O2+1
P2+1
Q2+1
R2+1
S2+1
T2+1
U2+1
V2+1
W2+1
X2+1
Y2+1
Z2+1
A3+1
B3+1
C3+1
D3+1
E3+1
F3+1
G3+1
H3+1
I3+1
J3+1
K3+1
L3+1
M3+1
N3+1
O3+1
P3+1
Q3+1
R3+1
S3+1
T3+1
U3+1
V3+1
W3+1
X3+1
Y3+1
Z3+1
A4+1
B4+1
C4+1
D4+1
E4+1
F4+1
G4+1
H4+1
I4+1
J4+1
K4+1
L4+1
M4+1
N4+1
O4+1
P4+1
Q4+1
R4+1
S4+1
T4+1
U4+1
V4+1
W4+1
X4+1
Y4+1
Z4+1
A5+1
B5+1
C5+1
D5+1
E5+1
F5+1
G5+1
H5+1
I5+1
J5+1
K5+1
L5+1
M5+1
N5+1
O5+1
P5+1
Q5+1
R5+1
S5+1
T5+1
U5+1
V5+1
W5+1
X5+1
Y5+1
Z5+1
A6+1
B6+1
C6+1
D6+1
E6+1
F6+1
G6+1
H6+1
I6+1
J6+1
K6+1
L6+1
M6+1
N6+1
O6+1
P6+1
Q6+1
R6+1
S6+1
T6+1
U6+1
V6+1
W6+1
X6+1
Y6+1
Z6+1
A7+1
B7+1
C7+1
D7+1
E7+1
F7+1
G7+1
H7+1
I7+1
J7+1
K7+1
L7+1
M7+1
N7+1
O7+1
P7+1
Q7+1
R7+1
S7+1
T7+1
U7+1
V7+1
W7+1
X7+1
Y7+1
Z7+1
A8+1
B8+1
C8+1
D8+1
E8+1
F8+1
G8+1
H8+1
I8+1
J8+1
K8+1
L8+1
M8+1
N8+1
O8+1
P8+1
Q8+1
R8+1
S8+1
T8+1
U8+1
V8+1
W8+1
X8+1
Y8+1
Z8+1
A9+1
B9+1
C9+1
D9+1
E9+1
F9+1
G9+1
H9+1
I9+1
J9+1
K9+1
L9+1
M9+1
N9+1
O9+1
P9+1
Q9+1
R9+1
S9+1
T9+1
U9+1
V9+1
W9+1
X9+1
Y9+1
Z9+1
A0