You are on page 1of 5

10.

Vopseaua
{ Oimpiada republican 1993. } Se d tabloul bidimensional A[1..n, 1..m], n care sunt nscrise numere ntregi pozitive. De exemplu: ! 1! "! 1# 1 $! 1! 1! 1" #! %! &! #! %! &! '! 1! #! # #! '! $! '! # %! %! ! &! %! %! %! %! #! % %! Se d numrul r(ndului )i al coloanei cruiva element, de exemplu *&, +. S ne nc,ipuim c deasupra acestui element se vars vopsea )i ea se revars peste elementele vecine, dac valoarea lor nu dep)e)te valoarea elementului peste care de acuma s-a vrsat vopsea. .evrsarea poate avea loc numai n direc/ie orizontal )i vertical )i nu pe diagonal. 0n cazul nostru de la elementul *&, + vopseaua se va revrsa peste elementele * , +, * ,$+, *$,&+, *$, +, *$,$+. 0n cazul c(nd ini/ial vopseaua se vars peste elementul *&,%+ se va 1vopsi1 un singur element. De alctuit un program, care s determine numarul maxim de elemente peste care s-a vrsat vopseaua )i care sunt aceste elemente. 0n tabloul 2[1..n, 1..m] vom marca acele elemente pe care se revars vopseaua. 3onstantele di )i dj le 4olosim pentru a putea cerceta cele patru direc/ii, unde poate s se verse vopseaua. 3onstanta ok poate 4i luat arbitrar. program vopsea5 { Se "coloreaz" acele elemente care au valoarea mai mic sau egal cu care vine vopseaua. } const fni='vopsea.in'; fno='vopsea.out'; di:array[ ..!"of integer=#$ % %&%&'; d(:array[ ..!"of integer=#&%&%$ % '; o)=*; var fi%fo :te+t; v%n%m%i%(%):integer; i&%(& :integer; a%+ :array[ .. &&% .. &&"of integer; l :array[ .. &&&&"of record i%(:,yte; end; s%e :integer; procedure add*6,7:integer+5 ,egin inc#e'; l[e".i:=-; l[e".(:=.; +[-%.":=o); elementul din

end5 4unction inside*i,8:integer+:boolean5 ,egin inside:=#i/= 'and#i0=n'and#(/= 'and#(0=m'; end5 begin assign#fi%fni'; reset#fi'; read1n#fi%n%m'; read1n#fi%i&%(&'; for i:= to n do for (:= to m do ,egin read#fi%a[i%("'; +[i% (":=&; end; close#fi'; { fill23ar#+%sizeof#+'%&';} s:= ; e:=&; v:=a[i&%(&"; add#i&%(&';

.3ile #s0=e'do ,egin for ):= to ! do ,egin i:=l[s".i4di[)"; (:=l[s".(4d([)"; if inside#i%('and#a[i%("0=a[l[s".i%l[s".("'and#+[i%("=&'t3en add#i%('; end; inc#s'; end; assign#fo%fno';re5rite#fo'; .rite1n#fo%'6umarul ma+im de elemente peste care s$a varsat vopseaua este:'%e'; .rite1n#fo%'7opseaua curge peste:''; for i:= to n do for (:= to m do if +[i%("=o) t3en .rite1n#fo%'#'%i:*%'%'%(:*%''''; close#fo'; end. 9bserva/ie: :roblema ;vopseaua<poate 4i rezolvat )i prin alte metode, ins prin metoda de mai sus complexitatea e mai mic. Am explicat rezolvarea acestor probleme pentru a n/elege mai bine urmtoarea problem :

11.Problema labirintului.
=olose)te o alt variant a ;programrii dinamice, numit metoda undei . >abirintul unei ncperi l vom reprezenta n 4orm de tablou bidimensional, elementele cruia sunt ! sau 1* 1 va simboliza loc gol, iar ! va simboliza perete+. Deplasarea prin labirint e posibil numai pe orizontal )i vertical *)i nu pe diagonal+. =iind date coordonatele a dou elemente [i!, 8!] si [i1, 81], de alctuit un program, care s determine lungimea drumului minim din [i!, 8!] p(na n [i1, 81]. Datele de intrare se citesc din 4i)ierul labirint.in n 4elul urmtor: pe prima linie sunt scrise dimensiunile tabloului n )i m separate prin spa/iu5 pe a doua linie coordonatele i! )i 8!, separate prin spa/iu5 pe a treia linie coordonatele i1 si 81, separate prin spa/iu5 pe liniile urmtoare elementele tabloului bidimensional, care pot 4i ! sau 1 *1- inseamn trecere, !- zid+. .ezultatele vor 4i nscrise n 4i)ierul labirint.out n 4elul urmtor: pe prima linie: lungimea drumului minim gsit5 pe urmtoarele linii perec,i de numere, indic(nd coordonatele elementelor drumului minim de trecece5 9bserva/ie: - dac sunt mai multe drumuri minime, de a4i)at unul din ele5 - dac a)a drum nu-i, de nscris mesa8ul: Nu s-a gsit nici un drum ?xemplu: Intrare: %& %# #% 1!!! !11! !11! Ie ire: Drum gasit. >ungimea drumului este # *%,#+ * #,#+ *#,%+ @oi explica n ce const metoda undei. :ornim de la elementul A[i!, 8!], cruia i atribuim la nceput valoarea #. Aoate trecerile din A[io,8o] le vom marca prin %, toate trecerile din celulele marcate cu %, le vom marca prin &, ).a.m.d. Dac va exista drum de trecere din A[i !,8!] , n A[i1,81] *valoarea variabilei ok va deveni true+, atunci A[i1,81]-# va indica lungimea drumului minim. Dac valoarea variabilei ok va rm(ne !alse, atunci a)a drum nu-i )i a4i)m mesa8ul respectiv. :entru a a4i)a nu numai lungimea, ci )i o solu/ie ce arat un drum minim, am 4olosit tabloul A[1..n, 1..m]. 3obor(ndu-ne de sus *de la *i1, 81++ n 8os * la *io, 8o++, recursiv vom a4i)a acest drum.

@ectorul >[1..nBm] l-am 4olosit pentru a ne putea deplasa din A[i,8] n toate cele patru direc/ii, care sunt posibile. :rogram drumulCminimCntrCunClabirint5 { 1a,irint: 8ergem pe unit9i #constanta gol'. :erourile sunt ziduri #constanta zid' } 3onst fni=;input.t+t;; fno=;output.t+t;; gol= ; zid=&; di:array[ ..!"of integer=#$ % %&%&'; d(:array[ ..!"of integer=#&%&%$ % '; var fi%fo:te+t; n%m%i%(%):integer; i&%(&%i %( :integer; a%t:array[ .. &&% .. &&"of integer; l:array[ .. &&&&"of record i%(:,yte; end; s%e:integer; o):,oolean; procedure add*6,7,v,D:integer+5 ,egin inc#e'; l[e".i:=-; l[e".(:=.; a[-%.":=v; t[-%.":=); end5 4unction inside*i,8:integer+:boolean5 begin inside:=#i/= 'and#i0=n'and#(/= 'and#(0=m'; end5 procedure rec*i,8:integer+5 ,egin if t[i%("0/$ t3en rec#i$di[t[i%(""%($d([t[i%(""'; .rite1n#fo%;#<%i:*%;%;%(:*%;';'; end5 begin assign#fi%fni'; reset#fi'; read1n #fi%n%m'; read1n #fi%i&%(&'; read1n#fi%i %( '; for i:= to n do for (:= to m do read#fi%a[i%("'; close#fi'; s:= ; e:=&; add#i&%(&%*%&'; t[i&%(&":=$ ; o):=false; .3ile #s0=e'do ,egin for ):= to ! do ,egin i:=l[s".i4di[)"; (:=l[s".(4d([)"; if inside#i%('and#a[i%("=gol't3en ,egin add#i% (% a[l[s".i% l[s".("4 % )'; if #i=i 'and#(=( ' t3en ,egin {solutie} s:=e; o):=true; ,rea); end; end; end; inc#s'; end; assign#fo%fno';re5rite#fo'; if o) t3en ,egin .rite1n#fo%;=rum gsit. 1ungimea drumului este <%a[i %( "$*%;.;'; rec#i %( '; end else .rite1n#fo%;6u s$a gsit nici un drum;';

close#fo';
end.

Insulele;
program Insulele; uses crt; var t m,n,i,j insule gasit

: : : :

array [1..100,1..100] of integer; integer; integer; boolean;

procedure Insula(i,j:integer); begin if (i in [1..m]) and (j in [1..n]) and (t[i,j]=1) t en begin t[i,j]:=0; gasit:=true; insula(i,j!1); insula(i!1,j); insula(i,j"1); insula(i"1,j); end; end; BEGIN clrscr; #rite($%ati & si ': $);readln(m,n); #riteln($%ati matricea: $); for i:=1 to m do for j:=1 to n do begin goto(y(j)*,i!+);readln(t[i,j]); end; insule:=0; for i:=1 to m do for j:=1 to n do begin gasit:=false; insula(i,j); if gasit t en insule:=insule!1; end; if insule=0 t en #riteln($'u am gasit nici o insula.$) else #riteln($,m gasit $,insule,$ insule.$); readln; END.

You might also like