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