De la unu la mai mulți... Principiul inducției în geometrieDoru Popescu AnastasiuMetoda inducției matematice are aplicatii diverse. Un domeniu în care poate fi folosită este geometria. În continuare vom exemplifica acest lucru prezentând câteva probleme în a căror rezolvare vom aplica principiul amintit.
Aplicația 1 Fie n ł 2 un număr natural și a1, a2, ..., an, n numere reale strict pozitive. Să se verifice dacă aceste numere pot fi lungimile laturilor consecutive ale unui poligon. În caz afirmativ se va afișa mesajul DA, altfel mesajul NU.
Exemple Pentru n = 3 și numerele: 5 2 1.5 se va afișa: NU
Pentru n = 3 și numerele: 2 2 3.5 se va afișa: DA
Soluție Se poate demonstra prin inducție matematică (vezi [1] sau [3]) că numerele a1, a2, ..., an, pot fi lungimile laturilor unui poligon dacă și numai dacă: a1 < a2 + a3+ ... + an a2 < a1 + a3+ ... + an ... an < a1 + a2+ ... + an -1 Folosind acest rezultat programul care rezolvă problema este următorul: Listing APP1.PAS Program Aplicatia_1; type vector=array[1..100] of Real; var a:vector; i,n:Integer; s:Real; sw:Boolean;
Begin Write('n='); Readln(n); for i:=1 to n do begin Write('a(',i,')='); Readln(a[i]) end; s:=0; for i:=1 to n do s:=s+a[i]; sw:=true; for i:=1 to n do if a[i]>=s-a[i] then sw:=false; if sw then write('DA') else write('NU') End.
Aplicația 2 Se dă un poligon articulat P1P2...Pn în plan, pentru care se cunosc lungimile laturilor. Se cere să se deformeze poligonul până se ajunge la un triunghi (eventual degenerat). Se vor preciza: - vârfurile triunghiului; - pentru fiecare latură a triunghiului vârfurile poligonului pe care le conține.
Exemplu Pentru datele de intrare: n=5 P1P2=3 P2P3=10 P3P4=10 P4P5=5 P5P1=12 ieșirea va fi: Triunghiul are varfurile: P1P3P5 Latura P1P3 contine punctele: P2 Latura P3P5 contine punctele: P4
Soluție Problema poate fi rezolvată prin inducție matematică. Fie P(n) propoziția: "Un poligon cu n laturi poate fi deformat ajungându-se la un triunghi", n ł 4. Pentru un patrulater se aleg două laturi consecutive a căror sumă nu depășește suma celorlalte. Acestea realizează o latură a triunghiului, celelalte două fiind formate din laturile rămase ale patrulaterului. Deci P(4) este adevărată. Considerăm propoziția adevărată pentru un poligon cu n+1 laturi. Alegem două laturi consecutive a căror sumă nu depășește suma celorlalte laturi. Deformăm poligonul astfel încât cele două laturi să ajungă în prelungire. Astfel s-a format un poligon cu n laturi și cum P(n) a fost presupusă adevărată, rezultă că P(n+1) este adevărată. Deci propoziția P(n) este adevărată pentru orice număr natural n ł 4. Programul care rezolvă problema, bazându-se pe cele de mai sus, este următorul:
Listing APP2.PAS Program Aplicatia_2; var l:array[1..50] of Real; a:array[1..50,1..50] of Byte; d:array[1..50] of Byte; i,j,i1,j1,n:Byte; s:Real;
procedure interschimbare(var x,y:Byte); var aux:Byte; begin aux:=x; x:=y; y:=aux end;
Begin Write('n='); Readln(n); for i:=1 to n-1 do begin Write('P',i,'P',i+1,'='); Readln(l[i]) end; Write('P',n,'P',1,'='); Readln(l[n]); l[n+1]:=l[1]; s:=l[n]; for i:=1 to n-1 do begin d[i]:=2; a[i,1]:=i; a[i,2]:=i+1; s:=s+l[i] end; d[n]:=2; a[n,1]:=n; a[n,2]:=1; l[n+1]:=l[1]; d[n+1]:=d[1]; a[n+1,1]:=1; a[n+1,2]:=2; while n>3 do begin i:=1; while (i<=n) and (s<2*(l[i]+l[i+1])) do Inc(i); { S-au ales laturile i si i+1 care } { se vor transforma intr-o } { singura latura } if a[i,1]=a[i+1,1] then interschimbare(a[i,1],a[i,d[i]]); if a[i,1]=a[i+1,d[i+1]] then begin interschimbare(a[i,1],a[i,d[i]]); interschimbare(a[i+1,1],a[i+1, d[i+1]]) end; for j:=2 to d[i+1] do a[i,d[i]+j-1]:=a[i+1,j]; d[i]:=d[i]+d[i+1]-1; l[i]:=l[i]+l[i+1]; for i1:=i+2 to n do begin for j1:=1 to d[i1] do a[i1-1,j1]:=a[i1,j1]; l[i1-1]:=l[i1] end; Dec(n); for j:=1 to d[1] do a[n+1,j]:=a[1,j]; l[n+1]:=l[1]; d[n+1]:=d[1] end; Writeln('Triunghiul are varfurile:'); Write('P',a[1,1],'P',a[1,d[1]]); if (a[2,1]<>a[1,1]) and (a[2,1]<>a[1,d[1]]) then Writeln('P',a[2,1]) else Writeln('P',a[2,d[2]]); if d[1]>2 then begin Writeln('Latura ','P',a[1,1],'P', a[1,d[1]],' contine punctele:'); for j:=2 to d[1]-1 do Write('P',a[1,j],' '); Writeln end; if d[2]>2 then begin Writeln('Latura P',a[2,1],'P', a[2,d[2]],' contine punctele:'); for j:=2 to d[2]-1 do Write('P',a[2,j],' '); Writeln end; if d[3]>2 then begin Write('Latura P',a[3,1],'P', a[3,d[3]],' contine punctele:'); for j:=2 to d[3]-1 do Write('P',a[3,j],' ') end End.
Aplicația 3 Se dă un poligon convex A1A2...Ak (kł3) prin coordonatele vârfurilor sale și 2n (nł1) puncte distincte prin coordonatele lor situate în interiorul poligonului. Să se împartă poligonul A1A2...Ak în n+1 poligoane convexe astfel încât toate cele 2n puncte să se găsească pe frontierele acestor poligoane.
Exemplu Pentru k = 4, coordonatele vârfurilor poligonului: 10 30 20 80 70 60 60 15 20 5 n=2 și coordonatele punctelor din interiorul poligonului: 25 50 40 20 25 20 40 50 o soluție posibilă este: (61.11, 20.00) (60.00, 15.00) (20.00, 5.00) (14.00, 20.00) (10.00, 30.00) (14.00, 50.00) (67.78, 50.00) (61.11, 20.00) (14.00, 20.00) (14.00, 50.00) (20.00, 80.00) (70.00, 60.00) (67.78, 50.00)
Soluție Problema poate fi rezolvată prin inducție matematică astfel: Pentru n = 1, dreapta determinată de cele două puncte realizează împărțirea cerută. Presupunem proprietatea adevărată pentru n - 1 și fie 2n puncte în interiorul poligonului, n ł 2. Fixăm o dreaptă d care nu intersectează poligonul. Fie M punctul cel mai apropiat de d și N punctul ales dintre cele 2n - 1 puncte, pentru care unghiul format de dreapta MN cu dreapta d, măsurat în sens trigonometric este minim (sau maxim). Dreapta MN împarte poligonul în două poligoane convexe P1 și P2, astfel încât P1 nu conține în interior nici un punct din cele 2n puncte, iar P2 conține în interior cel mult 2n - 2 puncte. Aplicând ipoteza de inducție deducem că poligonul inițial se împarte în n + 1 poligoane convexe, pe ale căror laturi se află toate cele 2n puncte. Programul care rezolvă problema este următorul:
Listing APP3.PAS Program Aplicatia_3; type punct=record x,y:Real end; var a1,a2,a,p:array[1..100] of punct; v1,v2:array[1..3] of Integer; n,k,i,j,i0,jM,jN,d1,d2,p1,p2,k1, k2:Integer; min,minM,pa,pantaMIN:Real; pp1,pp2,pu:punct; sw:Boolean;
procedure elimin(i1,i2:Integer); var j,h:Integer; q:array[1..100] of punct; begin h:=0; for j:=1 to 2*n do if (j<>i1) and (j<>i2) then begin Inc(h); q[h]:=p[j] end; for j:=1 to k do p[j]:=q[j]; Dec(n) end; { elimin }
procedure intersectie(P1,P2,P3,P4:punct; var P:punct); var a1,b1,c1,a2,b2,c2:Real; begin a1:=P2.y-P1.y; b1:=P1.x-P2.x; c1:=P1.y*(P2.x-P1.x)-P1.x*(P2.y-P1.y); a2:=P4.y-P3.y; b2:=P3.x-P4.x; c2:=P3.y*(P4.x-P3.x)-P3.x*(P4.y-P3.y); P.x:=(b1*c2-b2*c1)/(a1*b2-a2*b1); P.y:=(a2*c1-a1*c2)/(a1*b2-a2*b1) end; { intersectie }
function pozpunct(P1,P2,P:punct):Integer; var a,b,c:Real; begin a:=P2.y-P1.y; b:=P1.x-P2.x; c:=P1.y*(P2.x-P1.x)-P1.x*(P2.y-P1.y); if a*P.x+b*P.y+c>0 then pozpunct:=1 else if a*P.x+b*P.y+c<0 then pozpunct:=-1 else pozpunct:=0 end; { pozpunct } function panta(P1,P2:punct):Real; var pa,d:Real; begin d:=Sqrt(Sqr(P1.x-P2.x)+Sqr(P1.y-P2.y)); panta:=(P2.x-P1.x)/d end; { panta }
Begin Write('k='); Readln(k); Writeln('Coord. varfurilor poligonului:'); for i:=1 to k do begin Writeln('Punctul ',i); Write('abscisa='); Readln(a[i].x); Write('ordonata='); Readln(a[i].y) end; a[k+1]:=a[1]; Write('n='); Readln(n); Writeln('Coord. punctelor din', 'interiorul poligonului:'); for i:=1 to 2*n do begin Writeln('Punctul ',i); Write('abscisa='); Readln(p[i].x); Write('ordonata='); Readln(p[i].y) end; min:=a[1].y; j:=1; for i:=2 to k do if min>a[i].y then begin min:=a[i].y; j:=i end; while n>0 do begin { Determinare M } jM:=1; minM:=p[1].y; for i:=2 to 2*n do if minM>p[i].y then begin minM:=p[i].y; jM:=i end; { Determinare N } pantaMIN:=30000; for i:=1 to 2*n do if i<>jM then begin pa:=panta(p[jM],p[i]); if pa<pantaMIN then begin pantaMIN:=pa; jN:=i end end; { Gasirea celor doua poligoane } { determinate de MN } d1:=0; d2:=0; i0:=0; for i:=1 to k do begin p1:=pozpunct(p[jM],p[jN],a[i]); p2:=pozpunct(p[jM],p[jN],a[i+1]); if p1*p2<0 then begin Inc(d1); v1[d1]:=i; i0:=i end else if p1=0 then begin Inc(d2); v2[d2]:=i end; if (i0<>0) and (p1<>0) then begin i0:=i; pu:=a[i] end end; { Dreapta MN intersecteaza poligonul } { in interiorul laturilor } if d1=2 then begin intersectie(p[jM],p[jN],a[v1[1]], a[v1[1]+1],pp1); intersectie(p[jM],p[jN],a[v1[2]], a[v1[2]+1],pp2); for i:=k downto v1[1]+1 do a[i+1]:=a[i]; a[v1[1]+1]:=pp1; Inc(k); for i:=k downto v1[2]+2 do a[i+1]:=a[i]; a[v1[2]+2]:=pp2; Inc(k) end else { Dreapta MN intersecteaza o latura } { in interior si trece printr-un } { varf al poligonului } if d1=1 then begin intersectie(p[jM],p[jN],a[v1[1]], a[v1[1]+1],pp1); for i:=k downto v1[1]+1 do a[i+1]:=a[i]; a[v1[1]+1]:=pp1; Inc(k) end; k1:=0; k2:=0; p2:=pozpunct(p[jM],p[jN],pu); for i:=1 to k do begin p1:=pozpunct(p[jM],p[jN],a[i]); if p1*p2>=0 then begin Inc(k1); a1[k1]:=a[i] end; if p1*p2<=0 then begin Inc(k2); a2[k2]:=a[i] end end; p1:=pozpunct(p[jM],p[jN],pu); sw:=true; for i:=1 to 2*n do begin p2:=pozpunct(p[jM],p[jN],p[i]); if p1*p2>0 then sw:=false end; if n=1 then begin for i:=1 to k1 do Write('(',a1[i].x:4:2,',', a1[i].y:4:2,') '); Writeln; for i:=1 to k2 do Write('(',a2[i].x:4:2,',', a2[i].y:4:2,') '); Writeln; elimin(jM,jN) end else if sw then begin for i:=1 to k1 do Write('(',a1[i].x:4:2,',', a1[i].y:4:2,') '); Writeln; for i:=1 to k2 do a[i]:=a2[i]; k:=k2; a[k+1]:=a[1]; elimin(jM,jN) end else begin for i:=1 to k2 do Write('(',a2[i].x:4:2,',', a2[i].y:4:2,') '); Writeln; for i:=1 to k1 do a[i]:=a1[i]; k:=k1; a[k+1]:=a[1]; elimin(jM,jN) end end End.
Aplicația 4 Se dau 8n - 4 puncte dispuse sub formă de cruce (vezi figura). În câte moduri putem alege din aceste puncte câte patru, astfel încât ele să fie vârfurile unui pătrat?
Exemplu Pentru n=3 se va afișa: 21
Soluție Vom demonstra prin inducție că numărul căutat este 10n-9. Pentru n = 1, evident, putem obține 1 = 10 - 1 - 9 pătrate. Se poate dovedi ușor, printr-o simplă numărare, că pentru n = 2 putem alege 10 - 2 - 9 = 11 pătrate. Considerăm afirmația adevărată pentru n = k, unde k ł 2 și o demonstrăm pentru n = k + 1. Considerăm acum figura formată din 8(k + 1) - 4 puncte (în desen am considerat k = 3). Conform ipotezei de inducție putem alege exact 10k - 9 pătrate astfel încât fiecare să nu aibă nici un vârf în punctele A, B, C, D, E, F, G, H. Să considerăm acum pătratele având unul din vârfuri în A. Se observă ușor că există doar trei asemenea pătrate: ABB1A1, ACEG, AC1F1H. În concluzie, există exact zece pătrate cu proprietatea că cel puțin unul dintre vârfuri este unul dintre punctele A, B, C, D, E, F, G, H: patru pătrate congruente cu AC1F1H, patru pătrate congruente cu ABB1A1 și pătratele ACEG și BDFH. Numărul total de pătrate este (10k - 9) + 10 = 10(k + 1) - 9. În continuare propunem cititorului realizarea unui program care să afișeze numărul de pătrate, precum și pătratele, notând vârfurile coliniare cu o anumită literă și folosind indici numerotați de sus în jos și de la stânga la dreapta.
Bibliografie 1. L. Nicolescu etc., Metode de rezolvare a problemelor de geometrie, Editura Universității București, 1993 2. L. Panaitopol etc., Inducția matematică, Editura GIL, Zalău, 1997; 3. M. Pimsner, S. Popa, Probleme de geometrie elementară, Editura Didactică și Pedagogică, 1979 4. Doru Popescu Anastasiu, Principiul inducției în informatică, Gazeta de Informatică 3/1998; 5. Doru Popescu Anastasiu, Principiul inducției în informatică, Gazeta de informatică 6/1999; 6. W. Sierpinski, Elementary Theory of Numbers, Warszawa, 1987.
Dl. prof. Doru Popescu Anastasiu este cadru didactic la Colegiul Național "Radu Greceanu" din Slatina. Poate fi contactat prin e-mail la adresa dopopescu@pcnet.pcnet.ro. [cuprins] |