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.

[BACK]


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.

[BACK]


 

 

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

[BACK]