Alegeri (Pregatire Cluj, aprilie 1996)

Numele programului: p2.pas sau p2.c sau p2.cpp
Numele fisierului de intrare: p2.in
Numele fisierului de iesire:  p2.out

     Elevii unei scoli trebuie sa aleaga o persoana care sa-i reprezinte la o 
ntrunire nationala. Exista doar 2 candidati, iar fiecare dintre cei n elevi 
care voteaza trebuie sa aleaga pe unul dintre ei. 
Votarea se face n felul urmator:
     Cei n elevi sunt mpartiti n grupe egale. Apoi, fiecare grupa si alege un 
reprezentant care ntruneste cele mai multe adeziuni n grupul respectiv. 
Acesti reprezentanti sunt mpartiti din nou n grupuri egale, alegndu-se un 
nou reprezentant etc., iar cei care se afla n cea din urma etapa a acestor 
alegeri vor alege reprezentantul scolii.
     Stiind ca primul candidat are voie sa alcatuiasca componenta fiecarei grupe 
n parte, sa se determine numarul minim de alegatori de care are nevoie pentru 
a fi votat si sa se determine de cte etape de votare este nevoie pentru a putea 
fi ales.
     Sa se listeze pentru fiecare etapa de votare componenta grupelor.
Restrictii:
  1) n trebuie sa admita la descompunerea n factori primi doar numere impare;
  2) grupele se vor reprezenta ca o succesiune de '1' si '2', '1' nsemnnd ca 
elevul respectiv voteaza cu primul candidat, iar '2' nsemnnd ca voteaza cu al
doilea candidat.
Intrarea: 
Fisierul text de intrare contine pe fiecare linie cte o valoare a lui n.
Iesirea: 
Fisierul text de iesire contine datele de iesire corespunzatoare fiecarei valori 
a lui n din fisierul de intrare:
  - numarul minim de sustinatori pe o linie
  - mai multe linii corespunzatoare fiecarei etape care cuprind: numarul etapei 
pe o linie si continutul fiecarei grupe pe liniile urmatoare.
Exemplu: 
n=15
Numarul minim de sustinatori necesari primului candidat este
6.
Votarea are loc n 2 etape:
Etapa 1:
      11122
      11122
      22222
Etapa 2:
      112
========================================================
Teste:
15
35
105
3
9
27
33
================
Rezultate:
6
etapa 1
11122
11122
22222
etapa 2
112

12
etapa 1
1111222
1111222
1111222
2222222
2222222
etapa 2
11122

24
etapa 1
1111222
1111222
1111222
1111222
1111222
1111222
2222222
2222222
2222222
2222222
2222222
2222222
2222222
2222222
2222222
etapa 2
11122
11122
etapa 3
112

2
etapa 1
112

4
etapa 1
112
112
222
etapa 2
112

8
etapa 1
112
112
112
112
222
222
222
222
222
etapa 2
112
112
222
etapa 3
112

12
etapa 1
11111122222
11111122222
22222222222
etapa 2
112
=====================================
Solutia 1 (Angel Proorocu)
program OrganizareDeAlegeri;

  uses Crt;

  var x,grupe:array[1..15000]of integer;
      n:integer;
      f,g:text;

procedure afisez(k:integer);forward;

function prim(o:integer):boolean;
   var p:integer;
       r:real;
   begin;
       r:=sqrt(o);
       prim:=true;
       p:=1;
       while p<r do
        begin
         inc(p);
         if o mod p=0 then begin prim:=false; exit; end;
        end;
   end;

procedure rezolva;
   var i,j,k:integer;
   begin
     if x[n]=0 then
      for i:=1 to n do if n mod i=0 then
       begin
        if prim(i) then x[i]:=i div 2+1
         else
          begin
            x[i]:=i div 2+1;
            for j:=1 to i do for k:=j to i div j do if j*k=i then
             if grupe[j]=0 then
              if x[i]>x[j]*x[k] then
               begin
                x[i]:=x[j]*x[k];
                grupe[i]:=j;
               end;
          end;
       end;
      writeln(g,'Numarul minim de sustinatori (n=',n,'):');
      writeln(g,x[n]);
      afisez(1);
      writeln(g);
      writeln(g,'========================================================');
   end;

procedure afisez(k:integer);
  var i,j,gr,grn,grp,gg:integer;
  begin
    writeln(g,'Etapa ',k,':');
     if grupe[n]=0 then
      begin
        for i:=1 to n div 2+1 do write(g,'1');
        for i:=1 to n-n div 2-1 do write(g,'2');
        exit;
      end;
     gr:=x[n div grupe[n]];
     gg:=x[grupe[n]];
     for i:=1 to gr do
      begin
       for j:=1 to gg do write(g,'1');
       for j:=1 to grupe[n]-gg do write(g,'2');
       writeln(g);
      end;
     for i:=1 to n div grupe[n]-gr do
      begin
       for j:=1 to grupe[n] do write(g,'2');
       writeln(g);
      end;
    n:=n div grupe[n];
    afisez(k+1);
   end;

procedure ReadData;
   var nume:string;
       i:integer;
   begin
     for i:=1 to 10000 do
      begin x[i]:=0;
            grupe[i]:=0;
      end;
     clrscr;
     assign(f,'p2.in');
     reset(f);
     assign(g,'p2.out');
     rewrite(g);

     while not seekeof(f) do
       begin
         readln(f,n);
         rezolva;

       end;

    close(f);
    close(g);
    writeln('Rezultatele se afla in P2.OUT !!!');
    writeln('Apasati o tasta...');
    readkey;
  end;

begin
  ReadData;
end.
-----------------------------
