Sunteți pe pagina 1din 5

Concursul Naţional de Informatică Satu Mare

19-24 iulie 2009


Clasa a VI-a
Problema 2: Poza

Un fotograf pasionat doreşte să-şi păstreze în format electronic pozele din colecţia personală. Pentru
aceasta el scanează fotografiile, le prelucrează şi le salvează în format electronic.
Printre numeroasele sale fotografii a găsit o poză veche, de familie, care a fost deteriorată datorită
trecerii timpului, pe ea putându-se observa numeroase pete de forme şi dimensiuni diferite.
Fotograful îşi propune să scoată din imagine o parte dintre aceste pete, cele mai vizibile, prelucrându-
le la nivel de pixel şi colorându-le cu aceeaşi culoare ca a fondului pe care au fost identificate.
O „pată vizibilă” este o formaţiune de 3 pixeli de aceeaşi culoare, învecinaţi pe una din direcţiile N, E,
S, V, dar nu toţi situaţi pe orizontală sau pe verticală. „Pata vizibilă” poate fi identificată în fotografie
deoarece ea are altă culoare decât cea a fondului, fiind înconjurată de jur împrejur pe cele 4 direcţii
de pixeli coloraţi la fel. Pe marginea pozei nu pot fi identificate pete deorece, nu se poate decide dacă
nu cumva sunt părţi ale altor obiecte ce nu au fost surprinse în întregime în poză.
Cerinţă
Fiind dată o poză, număraţi câte „pete vizibile” are şi scoateţi-le pe toate, colorându-le cu aceeaşi
culoare ca a fondului pe care au fost identificate.

Date de intrare
Din fişierul poza.in se citesc:
- de pe primul rând m şi n reprezentând dimensiunile pozei,
- de pe următoarele m linii, câte n numere despărţite printr-un spaţiu, fiecare număr reprezintă
codificarea culorii unui pixel

Date de ieşire
În fişierul poza.out
- pe prima linie se va afişa numărul petelor,
- pe următoarele m linii, câte n numere despărţite printr-un spaţiu, fiecare număr reprezintă
codificarea culorii unui pixel din poza prelucrată (după ce au fost scoase „petele vizibile”)

Restricţii şi precizări
 4<=m<=200
 4<=n<=200
 culoarea unui pixel este un număr întreg din intervalul [1,16].
 dacă poza nu are „pete vizibile” în fişierul de ieşire se va afişa doar 0 (zero)
 poza nu conţine pete lipite (ce pot avea pixeli vecini pe una din cele 4 direcţii)
Exemplu:
poza.in poza.out
86 2
166456 166456
622671 666671
662681 666681
126251 126251
429422 429422
344342 344442
343342 344442
124429 124429
Timp maxim de execuţie/test: 1 secundă
#include <stdio.h>
#include <stdlib.h>
#define ML 201
#define MC 201
char p[ML][MC],lc[MC],lu[MC]; //p - poza; lc - linia curenta; lu - linia urmatoare
int m,n,np;
void cit(void)
{
FILE *f;
int i,j;
if( (f=fopen("poza.in","r"))==NULL)
{
fprintf(stderr,"\n\nERROARE INTRARE\n\n");
exit(1);
}
fscanf(f,"%d %d ",&m,&n);
for(i=1;i<=m;i++)
for(j=1;j<=n;j++)
fscanf(f," %d ",&p[i][j]);
fclose(f);
}
int f1(int li, int co)
{ int cp,cf;
cp=p[li][co];//culoare pata
cf=p[li][co-1];//culoare fond
if((cp==p[li][co+1])&& //determinare forma 1
(cp==p[li+1][co+1])&&
(cp!=cf)&& // verifica pata<>fond
(cf==p[li-1][co])&& // verificare contur forma 1
(cf==p[li-1][co+1])&&
(cf==p[li][co+2])&&
(cf==p[li+1][co+2])&&
(cf==p[li+2][co+1])&&
(cf==p[li+1][co]) )
{
p[li][co]=p[li][co+1]=p[li+1][co+1]=cf;//fill
return 1;
}
return 0;
}
int f2(int li, int co)
{ int cp,cf;
cp=p[li][co];//culoare pata
cf=p[li][co-1];//culoare fond
if((cp==p[li][co+1])&&
(cp==p[li+1][co])&&
(cp!=cf)&&
(cf==p[li-1][co])&&
(cf==p[li-1][co+1])&&
(cf==p[li][co+2])&&
(cf==p[li+1][co+1])&&
(cf==p[li+2][co])&&
(cf==p[li+1][co-1]))
{
p[li][co]=p[li][co+1]=p[li+1][co]=cf;
return 1;
}
return 0;
}
int f3(int li, int co)
{ int cp,cf;
cp=p[li][co];//culoare pata
cf=p[li][co-1];//culoare fond
if((cp==p[li+1][co+1])&&
(cp==p[li+1][co])&&
(cp!=cf)&&
(cf==p[li-1][co])&&
(cf==p[li][co+1])&&
(cf==p[li+1][co+2])&&
(cf==p[li+2][co+1])&&
(cf==p[li+2][co])&&
(cf==p[li+1][co-1]))
{
p[li][co]=p[li+1][co+1]=p[li+1][co]=cf;
return 1;
}
return 0;
}
int f4(int li, int co)
{ int cp,cf;
cp=p[li][co];//culoare pata
cf=p[li][co-1];//culoare fond
if((cp==p[li+1][co])&&
(cp==p[li+1][co-1])&&
(cp!=cf)&&
(cf==p[li-1][co])&&
(cf==p[li][co+1])&&
(cf==p[li+1][co+1])&&
(cf==p[li+2][co])&&
(cf==p[li+2][co-1])&&
(cf==p[li+1][co-2]))
{
p[li][co]=p[li+1][co]=p[li+1][co-1]=cf;
return 1;
}
return 0;
}
void afis(void)
{
FILE *f;
int i,j;
if( (f=fopen("poza.out","w"))==NULL)
{
fprintf(stderr,"\n\nERROARE IESIRE\n\n");
exit(1);
}
fprintf(f,"%d",np);
if(np)
for(i=1;i<=m;i++)
{ fprintf(f,"\n");
for(j=1;j<=n;j++)
fprintf(f,"%d ",p[i][j]);

}
fclose(f);
}
int main()
{
int i,j,idf,k; //np - nr. de pe, idf - id de forma
cit();
for (k=2;k<=n-1;k++) lu[k]=1;// init validul ptr. linia urmatoare
for(i=2;i<=m-2;i++) //ptr. fiec linie 2..m-2
{
for (k=2;k<=n-1;k++)
{
lc[k]=lu[k]; //copiez lin urm. peste lin curenta
lu[k]=1; // init linia urmatoare
}
for(j=2;j<=n-1;j++) //pentru fiec col 2..n-1
{
if(lc[j]) //daca valid-ul de pe linia curenta ma lasa, adica pozitia merita testata
{
idf=1;// inca nu am gasit forma
if(idf&&(j<n-1)&&f1(i,j))
{
np++; //nr de pete creste
lu[j]=lu[j+1]=lu[j+2]=0; //pe linia urmatoare marchez poz pe care
nu mai caut
j+=2; // sar in dr. peste 2 poz
idf=0; //am gasit o forma nu mai incerc cu celelalte
}
if(idf&&(j<n-1)&&f2(i,j))
{
np++;idf=0;
lu[j-1]=lu[j]=lu[j+1]=0;
j+=2;
}
if(idf&&(j<n-1)&&f3(i,j))
{
np++;idf=0;
lu[j-1]=lu[j]=lu[j+1]=lu[j+2]=0;
j+=1;
}
if(idf&&(j>2)&&f4(i,j))
{
np++;idf=0;
lu[j-2]=lu[j-1]=lu[j]=lu[j+1]=0;
j+=1;
}
}
}
}
afis();
return 0;
}

S-ar putea să vă placă și