www.agora.ro
Primul, al doilea și … ceilalți

 

PRINCIPIUL inducției în informatică

Doru Popescu Anastasiu

În continuare ne propunem să prezentăm probleme care pot fi rezolvate prin inducție matematică și permit scrierea de algoritmi. Datorită procesului iterativ de generare a soluțiilor se obțin în general algoritmi liniari.

P1: Perechi de numere

Se dau n (nł1) perechi de numere întregi (a1,b1), (a2,b2),...,(an,bn). Să se determine două numere întregi c și d cu proprietatea:

a12+b12)(a22+ b 22)...(an2+bn2)=c2+d2

.

 

Exemplu

Pentru n=3 și perechile:

2 3

1 3

2 2 se va afișa:

c=28

d=16

Soluție

Construcția numerelor c și d se poate realiza prin inducție matematică.

Dacă n=1 atunci putem lua c=a1 și d=b1.

Dacă (a12+b12)(a22+b22)...(ak2+bk2)=e2+f2, atunci putem lua c=eak+1+fbk+1 și d=ebk+1-fak+1 pentru a obține:

(a12+b12)(a22+b22)...(ak2+bk2)(ak+12+bk+12)=c2+d2.

Listing: P1.PAS

program p1;

var a,b:array[1..500] of Longint;

c,d,c1,d1,n,i:Longint;

Begin

Write('n='); Readln(n);

for i:=1 to n

do

begin

Write('Dati perechea ',i);

Readln(a[i],b[i])

end;

c:=a[1]; d:=b[1];

for i:=2 to n do

begin

c1:=c*a[i]+d*b[i];

d1:=Abs(c*b[i]-d*a[i]);

c:=c1; d:=d1

end;

Writeln('c=',c);

Writeln('d=',d)

End.

P2: Număr par

Se consideră un număr natural par m. Se cere să se determine două numere naturale x și y, astfel încât m=(x+y)2+3x+y.

Exemplu

Pentru m=6 se va afișa:

x=0; y=2

Soluție

Determinarea numerelor x și y o vom face prin inducție matematică, notându-le cu xn și yn unde m=2n.

Dacă m=0, putem lua x0=y0=0. Dacă afirmația este adevărată pentru n număr natural, atunci avem:

2n=(xn+yn)2+3xn+yn.

Pentru a găsi xn+1 și yn+1 cu proprietatea:

2n+2=(xn+1+yn+1)2+3xn+1+yn+1 (*),

distingem cazurile:

I. yn=0, atunci putem lua xn+1=0; yn+1=xn+1 și (*) este verificată.

II. yn=1, atunci, pentru xn+1=xn+1 și yn+1=yn-1, obținem (*).

Listing: P2.PAS

program p2;

var m,x,y,x1,y1,i:Longint;

Begin

Write('Introduceti un numar natural par ');

Readln(m);

m:=m div 2;

x:=0; y:=0;

for i:=1 to m do

begin

if y=0 then begin x1:=0; y1:=x+1 end

else begin x1:=x+1; y1:=y-1 end;

x:=x1; y:=y1

end;

Writeln('x=',x); Writeln('y=',y)

End.

P3: Soluția unei ecuații

Pentru n număr natural, (nł6). Să se determine o soluție în mulțimea numerelor naturale a ecuației:

1/x12 + 1/x22 + . . . + 1/xn2 =1.

Exemplu

Pentru n=7 o soluție este:

2 2 2 4 4 4 4

Soluție

Soluția problemei poate fi construită inductiv cu pasul 3, astfel:

· pentru n=6, avem:

1/22+1/22+1/22+1/32+1/32+1/62=1;

· pentru n=7, avem:

1/22+1/22+1/22+1/42+1/42+1/42+1/42=1;

· pentru n=8, avem:

1/22+1/22+1/22+1/32+1/32+1/72+1/142+1/212=1.

Dacă pentru n avem:

1/x12+1/x22+...+1/xn2=1, atunci pentru n+3, avem:

1/x12+1/x22+...+1/xn-12+1/(4xn2)+

1/(4xn2)+1/(4xn2)+1/(4xn2)=1,

și deci soluția este

(x1,x2,...,xn-1,2xn,2xn,2xn,2xn).

Listing: P3.PAS

program p3;

type vector=array[1..100]of Longint;

var x,y,z:vector;

temp:Longint;

i,k,n,rest,dimx,dimy,dimz:Integer;

procedure afisare(v:vector; dim:Integer);

var j:Integer;

begin

for j:=1 to dim do Write(v[j],' ');

Writeln

end;

Begin

Write('n='); Readln(n); dimx:=6;

x[1]:=2; x[2]:=2; x[3]:=2;

x[4]:=3; x[5]:=3; x[6]:=6;

for i:=1 to 3 do y[i]:=2;

for i:=4 to 7 do y[i]:=4;

dimy:=7; dimz:=8;

for i:=1 to 3 do z[i]:=2;

z[4]:=3; z[5]:=3;

z[6]:=7; z[7]:=14; z[8]:=21;

for i:=9 to n do

begin

rest:=i mod 3;

case rest of

0:begin

temp:=x[dimx]; dimx:=dimx+3;

for k:=0 to 3 do x[dimx+k-3]:=2*temp

end;

1:begin

temp:=y[dimy]; dimy:=dimy+3;

for k:=0 to 3 do y[dimy-3+k]:=2*temp

end;

2:begin

temp:=z[dimz]; dimz:=dimz+3;

for k:=0 to 3 do z[dimz-3+k]:=2*temp

end

end

end;

rest:=n mod 3;

case rest of

0: afisare(x,dimx);

1: afisare(y,dimy);

2: afisare(z,dimz)

end

End.

P4: O împărțire a unui poligon convex

(propusă la ONI ‘99, clasele XI-XII)

Enunțul problemei a fost publicat în numărul 5 al GInfo.

Soluție

a) Se observă că numărul vârfurilor unui poligon cu centru de simetrie este par. Verificarea existenței punctului de simetrie se reduce la a arăta că laturile opuse două câte două sunt paralele și congruente.

b) Determinarea descompunerii se poate face prin inducție matematică astfel:

· dacă n este 4 atunci poligonul este chiar un paralelogram;

· pentru un poligon A1A2...An alegem două laturi opuse paralele, spre exemplu A1A2 și An/2+2An/2+1 și translatăm spre stânga pe direcția A1A2 cu lungimea A1A2 linia poligonală An/2+2An/2+3...AnA1 obținând n/2-1 paralelograme și un poligon convex cu n-2 vârfuri, care moștenește proprietatea de a avea centru de simetrie. Astfel problema a fost redusă la împărțirea unui poligon cu n-2 vârfuri.

Listing: P4.PAS

program partitie_poligon;

type punct=record x,y:Integer end;

sir=array[1..101] of punct;

var a,b:sir; n,i:Integer; f:Text;

function paralele(p1,p2,q1,q2:punct):Boolean;

var sw:Boolean; m1,m2:Real;

begin

if p1.x=p2.x

then sw:=q1.x=q2.x

else

if q1.x=q2.x then sw:=false

else

begin

m1:=(p1.y-p2.y)/(p1.x-p2.x);

m2:=(q1.y-q2.y)/(q1.x-q2.x);

sw:=m1=m2

end;

paralele:=sw

end;

function seg_eg(p1,p2,q1,q2:punct):Boolean;

var l1,l2:Longint;

begin

l1:=sqr(p1.x-p2.x)+sqr(p1.y-p2.y);

l2:=sqr(q1.x-q2.x)+sqr(q1.y-q2.y);

seg_eg:=l1=l2

end;

function centru_sim:Boolean;

var sw:Boolean;

begin

if n mod 2=1

then sw:=false

else

begin

sw:=true;

for i:=1 to n div 2 do

begin

if not paralele(a[i],a[i+1],

a[n div 2 +i],a[n div 2+i+1])

then sw:=false;

if not seg_eg(a[i],a[i+1],

a[n div 2 +i],a[n div 2+i+1])

then sw:= false

end

end;

centru_sim:=sw

end;

procedure impartire(n:Integer; a:sir);

var j,k:Integer;

begin

if n=4 then

begin

Write(f,a[1].x,' ',a[1].y,' ',a[2].x);

Write(' ',a[2].y,' ',f,a[3].x,' ');

Write(a[3].y,' ',a[4].x,' ',a[4].y);

end

else

begin

j:=n div 2 +2;

while j<=n do

begin

Write(f,a[j].x,' ',a[j].y,' ');

Write(a[j+1].x,' ',a[j+1].y,' ');

Write(f,a[j+1].x+a[2].x-a[1].x,' ');

Write(a[j+1].y+a[2].y-a[1].y,' ');

Write(f,a[j].x+a[2].x-a[1].x,' ');

Writen(a[j].y+a[2].y-a[1].y);

j:=j+1

end;

for j:=1 to n div 2 do b[j]:=a[j+1];

k:=n div 2;

for j:=n div 2 +3 to n do

begin

k:=k+1;

b[k].x:=a[j].x+a[2].x-a[1].x;

b[k].y:=a[j].y+a[2].y-a[1].y

end;

for i:=1 to k do a[i]:=b[i];

a[k+1]:=a[1];

impartire(k,a)

end

end;

Begin

Assign(f,'POLIGON.IN'); Reset(f);

Readln(f,n);

for i:=1 to n do Readln(f,a[i].x,a[i].y);

a[n+1]:=a[1]; Close(f);

Assign(f,'POLIGON.OUT'); Rewrite(f);

if not centru_sim then Write(f,'NU')

else

begin Writeln(f,'DA'); impartire(n,a) end;

Close(f)

End.

Bibliografie

1. Titu Andreescu - O extindere a unei probleme de teoria numerelor, Gazeta Matematică Nr. 1/1980;

2. Constantin Cocea - Două teoreme de reprezentare de tip Erdos-Suranyi, Revista de Matematică din Timișoara, Nr. 1/1998;

3. Ion Cucurezeanu - Probleme de aritmetică și teoria numerelor, Ed. Tehnică 1976;

4. L. Panaitopol, etc. - Inducția Matematică, Editura GIL, Zalău, 1997;

5. Doru Popescu Anastasiu - Principiul inducției în informatică, Gazeta de Informatică 3/1998;

6. W. Sierpinski - Elementary Theory of Numbers, Warszawa, 1987.

Domnul Doru Popescu Atanasiu este cadru didactic la liceul "Radu Greceanu", Slatina. Poate fi contactat prin intermediul redacției.

[cuprins]