Probleme de Informatica Rezolvate

Descărcați ca docx, pdf sau txt
Descărcați ca docx, pdf sau txt
Sunteți pe pagina 1din 31

#include<iostream> /// PAGE 1

#include<fstream>

using namespace std;

/// PROMBLEMA 1 => CERINTA: Aflati secventa de suma maxima dintr-un vector de
numere intregi si determinati indicii de inceput si final ai acesteia.

ifstream fin("ssmax.in");

ofstream fout("ssmax.out");

int main ()

int smax,s,i,n,a[100],st,dr,x,y;

fin>>n;

for (i=1;i<=n;i++)

fin>>a[i]; /// citire

s=a[1]; st=1; dr=1; /// initializari

if (s<0) s=0;

else smax=s;

/// st si dr sunt auxiliare , iar x si y mentin solutiile

for (i=2;i<=n;i++)

s+=a[i];

if (s>smax)

{ smax=s; x=st; y=i; }

if (s<0)

{ s=0; st=i+1; dr=i+1; }

fout<<"secventa de suma maxima este "<<smax;

fout<<" iar aceasta incepe cu termenul al "<<x<<"-lea"<<" si se termina cu


termenul al "<<y<<"-lea.";

fin.close();

fout.close();

return 0;}
#include<iostream> /// PAGE 2

#include<fstream>

using namespace std;

/// PROMBLEMA 2 => CERINTA: Determina daca o secventa are un element


majoritar si afiseaza de cate ori apare acest in cadrul secventei.

ifstream fin("el-maj.in"); ofstream fout("el-maj.out");

int main ()

{ int a[100],i,n,k,cnt,x;

fin>>n;

for (i=1;i<=n;i++)

fin>>a[i];

cnt=1; x=a[1]; /// initializari

for (i=2;i<=n;i++)

if (a[i]==x) cnt++;

else cnt--;

if (cnt<0) x=a[i];

k=0;

for (i=1;i<=n;i++)

if (x==a[i]) k++;

if (k>=n/2+1) fout<<"in aceasta serie exista un element majoritar, "<<x<<", si


apare de "<<k<<" ori"<<endl;

else fout<<"in aceasta serie nu exista un element majoritar, dar


exista un element mai/la fel de frecvent decat majoritatea, "<<x<<", si apare de
"<<k<<" ori"<<endl;

fin.close();

fout.close();

return 0;

}
#include<iostream> /// PAGE 3

#include<fstream>

using namespace std;

#define Nmax 30000

/// PROMBLEMA 3 => CERINTA: Construiti un vector de numere natural cu primele


30000 numere naturale prime pintr-o metoda eficienta din punct de vedere al
timpului de executie.

ifstream fin("eratosthene.in"); ofstream fout("eratosthene.out");

int main ()

{ int a[Nmax],ok,i,j,k,prime[Nmax],n;

/// Vom folosi metoda Ciurului lui Erathostene, cunoscuta inca din antichitate

for (i=1;i<=Nmax;i++)

a[i]=0; /// a[i]=0 daca i e prim, si a[i]=1 daca i nu e prim;

for (i=3;i<=Nmax;i=i+2)

{ if (a[i]==0)

{ for (j=i*i;j<=Nmax;j=j+i*2) a[j]=1; }

k=0; prime[++k]=2;

for (i=3;i<=Nmax;i=i+2)

if (a[i]==0) prime[++k]=i;

n=k;

fout<<"Numerele prime mai mici ca 30000 sunt:"<<endl;

for (i=1;i<=n;i++)

fout<<prime[i]<<" ";

if (i%10==0) fout<<endl;

fin.close();

fout.close();

return 0;

}
#include<iostream> /// PAGE 4
#include<fstream>

using namespace std;

/// PROMBLEMA 4 => CERINTA: Din fisierul de intrare se citesc perechi n de


numere de forma x si y. Calculati pentru fiecare pereche cel mai mare divisor
comun printr-o metoda eficienta din punct de vedere al timpului de executie.

ifstream fin ("euclid.in");

ofstream fout("euclid.out");

int main ()

int n,i,r,a,b,x,y;

fin>>n;

for (i=1;i<=n;i++)

fin>>x>>y;

a=x; b=y;

/// Vom folosi binecunoscutul algoritm al lui Euclid

while (b!=0)

r=a%b;

a=b;

b=r;

fout<<a<<"\n";

fin.close();

fout.close();

return 0;

}
Numele problemei: diferenta ; Sursa: Olimpiada de Informatica Iasi 2015 /// PAGE 5

Link: http://campion.edu.ro/arhiva/index.php?page=problem&action=view&id=1638

Marius este pasionat de pătrate perfecte. Într-o matrice T cu n linii şi m coloane, Marius a scris numere naturale
nenule. Apoi construieşte o altă matrice NR, tot cu n linii şi m coloane. Elementul NR[i][j] = numărul de perechi de
pătrate perfecte a căror diferenţă este egală cu T[i][j] (1≤i≤n, 1≤j≤m).
1 ≤ n ≤ 100
• 1 ≤ m ≤ 100
• Numerele din matricea T sunt numere naturale nenule ≤ 40000.

Cunoscându-se numerele n, m şi matricea T, să se afişeze matricea NR, printr-o metoda eficienta din punct de
vedere al memoriei folosite si a timpului de executie a programului.

#include<fstream>
#include<algorithm>

#include<iostream>

using namespace std;

int patrate[20005], n, m, v[40005];

void Patrate()

int i;

for (i=1;i<=20001;i++)

patrate[i]=i*i;

int NrPerechi(int dif)

int i, j, cnt, x;

cnt = 0;

i = 0; j = 1;

while ( patrate[j]-patrate[j-1] <= dif)

x = patrate[j]-patrate[i];

if (x==dif)

{ cnt++; i++; j++;}

else

if (x<dif) j++;
else i++; /// PAGE 6

return cnt;

void CitireAfisare()

{ int i, j, x, y;

ifstream fin ("diferenta.in");

ofstream fout ("diferenta.out");

fin>>n>>m;

for (i=1;i<=n;i++)

{ for (j=1;j<=m;j++)

{ fin>>x;

if (v[x] == 0)

y=NrPerechi(x); v[x] = y;

else y = v[x];

fout<<y<<" ";

fout<<"\n";

fin.close(); fout.close();

int main()

Patrate();

CitireAfisare();

return 0;

}
Numele problemei: gradina ; Sursa: ONI 2013 /// PAGE 7

Link: http://campion.edu.ro/arhiva/index.php?page=problem&action=view&id=1530

Păcală a reuşit să ducă la bun sfârşit înţelegerea cu boierul căruia-i fusese slugă şi, conform învoielii, boierul trebuie
să-l răsplătească dându-i o parte din livada sa cu pomi fructiferi. Boierul este un om foarte ordonat, aşa că livada sa
este un pătrat cu latura de N metri unde, pe vremuri, fuseseră plantate N rânduri cu câte N pomi fiecare. Orice pom
fructifer putea fi identificat cunoscând numărul rândului pe care se află şi poziţia sa în cadrul rândului respectiv. Cu
timpul, unii pomi s-au uscat şi acum mai sunt doar P pomi. Păcală trebuie să-şi delimiteze în livadă o grădină pătrată
cu latura de K metri. Cunoscând dimensiunile livezii şi grădinii, numărul pomilor din livadă şi poziţia fiecăruia,
determinaţi numărul maxim de pomi dintr-o grădină pătrată de latură K şi numărul modurilor în care poate fi
amplasată grădina cu numărul maxim de pomi.

#include<fstream>

#include<algorithm>

using namespace std;

ifstream fin("gradina1.in");

ofstream fout("gradina1.out");

int a[1001][1001],s[1001][1001];

int k,ka,n,lin,col,x,maxim,i,j,p;

void Citire()

in>>n>>p>>k;

for (i=1; i<=p; i++)

in>>lin>>col;

a[lin][col]=1;

void Rezolva1()

s[1][1]=a[1][1];

for (i=2; i<=n; i++)

s[i][1]=s[i-1][1]+a[i][1];

for (i=2; i<=n; i++)

s[1][i]=s[1][i-1]+a[1][i];
for (i=2; i<=n; i++) /// PAGE 8

for (j=2; j<=n; j++)

s[i][j]=s[i][j-1]+s[i-1][j]+a[i][j]-s[i-1][j-1];

void Rezolva2()

maxim=-1;

ka=0;

for (i=k; i<=n; i++)

for (j=k; j<=n; j++)

x=s[i][j]-s[i-k][j]-s[i][j-k]+s[i-k][j-k];

if (maxim==x) ka++;

else if (maxim<x)

ka=1;

maxim=x;

} void Afisare()

{ fout<<maxim<<"\n"<<ka; }

int main ()

Citire();

Rezolva1();

Rezolva2();

Afisare();

fin.close(); fout.close();

return 0; }
Numele problemei: matrixel ; Sursa: XOR Vaslui 2013 /// PAGE 9

Link: http://campion.edu.ro/arhiva/index.php?page=problem&action=view&id=1474

Fie o matrice de numere naturale cu L linii numerotate de la 1 la L şi C coloane numerotate de la 1 la C. Din această
matrice se elimină P linii şi Q coloane. Să se afişeze matricea rămasă după ştergerea liniilor şi coloanelor.

#include<fstream>

using namespace std;

ifstream fin("matrixdel.in");

ofstream fout("matrixdel.out");

int main ()

int L,C,P,Q,c,i,j,linie,coloana,a[101][101],k;

fin>>L; fin>>C;

for (i=1;i<=L;i++)

for (j=1;j<=C;j++)

fin>>a[i][j];

fin>>P; // liniile care se sterg

for (c=1;c<=P;c++)

fin>>linie;

for (i=1;i<=C;i++)

a[linie][i]=-1;

in>>Q; // coloanele care se sterg

for (c=1;c<=Q;c++)

fin>>coloana;

for (i=1;i<=L;i++)

a[i][coloana]=-1;

for (i=1;i<=L;i++)
{ /// PAGE 10

k=0;

for (j=1;j<=C;j++)

{ if (a[i][j]!=-1)

{ fout<<a[i][j]<<" ";

k++;

if (k!=0) fout<<"\n";

fin.close();

fout.close();

return 0;

/////////////////////////////////////////////////////////////////////////////////////

Nume problema: sirul; Sursa: OJI 2003;

Link: http://campion.edu.ro/arhiva/index.php?page=problem&action=view&id=916

Să considerăm următorul şir:


a, b, ba, bab, babba, babbabab, ...

Cerinţă: Scrieţi un program care să determine care este cel de-al n-lea termen al şirului. Se citeste n-ul dintr-un
fisier.

#include<fstream>

#include<cstdio>

#include<cstring>

using namespace std;

ifstream fin("sirul.in");

ofstream fout("sirul.out");

int main ()

{ int n,i;

fin>>n;
char x[150],y[150],aux[150]; /// PAGE 11

x[0]='a'; x[1]=0; /// initilizari

y[0]='b'; y[1]=0; /// initializari

if (n==1) fout<<x; /// cazuri particulare

if (n==2) fout<<y; /// cazuri particulare

else

for (i=3;i<=n;i++)

strcpy(aux,y); /// aux = b

strcat(y,x); /// y = ba

strcpy(x,aux); /// x = b

} fout<<y<<"\n";

fin.close();

fout.close();

return 0;

/////////////////////////////////////////////////////////////////////////////////////

Numele problemei: ucif; Sursa: OJI 2005;

Fie n un număr natural şi s suma următoare:

s = 11+ 22 + 33 + … + nn

Cerinţă: Scrieţi un program care să afişeze ultima cifră a lui s.


#include<fstream>
using namespace std;
ifstream fin("ucif.in");
ofstream fout("ucif.out");
int main ()
{
int s,n,i,a,aux,j;
fin>>n; s=0;
for (i=1;i<=n;i++) /// PAGE 12
{
a=i%10; aux=1;
for (j=1;j<=i;j++)
{
aux=(aux*a)%10;
}
s=s+aux;
}

fout<<s%10;
fin.close();
fout.close();
return 0;
}

/////////////////////////////////////////////////////////////////////////////////////

Numele problemei: figura; Sursa: ONIG 2010;


Link: http://campion.edu.ro/arhiva/index.php?page=problem&action=view&id=1035
Dintr-o foaie de matematică pe care se află DxD pătrăţele aranjate în D linii şi D coloane a fost decupată o figură.
Figura decupată este compactă (nu are găuri) şi este formată din N pătrăţele de pe foaie.

Cerinţă: Scrieţi un program care să determine perimetrul figurii decupate.


#include<fstream>
using namespace std;
ifstream fin("figura.in");
ofstream fout("figura.out");
int a[22][22];
int main ()
{
int D,n,P,i,y,x,j;
fin>>D; fin>>n; P=0;
for (i=1;i<=n;i++)
{ in>>y; in>>x;
a[y+1][x+1]=1;}

for (i=1;i<=D+2;i++)
{
for (j=1;j<=D+2;j++)
{
if (a[i][j]==1)
{
if (a[i-1][j]==0)
P++;
if (a[i+1][j]==0)
P++;
if (a[i][j-1]==0)
P++;
if (a[i][j+1]==0)
P++;

}
}
}

fout<<P;
fin.close();
fout.close();
return 0;
}
Numele problemei: ecp; Sursa: XOR 2015 /// PAGE 13

Link: http://campion.edu.ro/arhiva/index.php?page=problem&action=view&id=1624

O expresie corect parantezată (prescurtat ecp) este un sir format din caracterele (,),[,],{,} si care se formează după
următoarele reguli:

 (), [],{} sunt ecp


 dacă A este ecp, atunci (A), [A] si {A} sunt ecp
 dacă A si B sunt ecp, atunci AB este ecp

Exemple de ecp: ({}{}[(())]), ((([]))), {({()}[])}. Exemple de siruri care nu sunt ecp: ([]], {(}). Costul unei ecp
se calculează astfel:

 () este o ecp de cost 2


 [] este o ecp de cost 3
 {} este o ecp de cost 5
 dacă A este ecp de cost k, atunci (A) are costul 22*k, [A] are costul 33*k, iar {A} are costul 55*k
 dacă A si B sunt ecp de costuri k si p, atunci expresia AB este o ecp de cost k*p.

De exemplu, costul expresiei ()[(()){}()] este 2*33*(22*(2)*5*2)=25*33*51=4320.

Cerinţă: Dându-se o expresie correct parantezata, să se determine costul acesteia.

#include <fstream>
using namespace std;

int main()
{
int doi,trei,cinci;
char a[1001];
int i,n;
ifstream fin("ecp.in");
fin>>a;
doi=trei=cinci=0;
for (i=0;a[i+1]!=0;i++)
{
if (a[i]=='(' && a[i+1]!=')')
doi=doi+2;
else if (a[i]=='(')
doi++;

if (a[i]=='[' && a[i+1]!=']')


trei=trei+3;
else if (a[i]=='[')
trei++;

if (a[i]=='{' && a[i+1]!='}')


cinci=cinci+5;
else if (a[i]=='{')
cinci++;
}

ofstream fout("ecp.out");
fout << doi << " " << trei << " " << cinci<< "\n";
fout.close();
return 0;
}

Numele problemei: foto; Sursa: OMI Iasi 2014 ///PAGE 14


Link: http://campion.edu.ro/arhiva/index.php?page=problem&action=view&id=1574
#include <fstream>
#include <algorithm>

using namespace std;

int a[105][105], n, m, cnt, cntmax;

void Citire()
{ int i, j;
ifstream fin ("foto.in");
fin>>n>>m;
for (i=1;i<=n;i++)
for (j=1;j<=m;j++)
fin>>a[i][j];
fin.close();
}
// bordeaza cu 1 matricea a
void Bordare()
{
int i;
for (i=0;i<=m+1;i++)
a[0][i]=a[n+1][i]=1;
for (i=0;i<=n+1;i++)
a[i][0]=a[i][m+1]=1;
}

void Fill(int i, int j)


{
if (a[i][j] == 0)
{
cnt++;
a[i][j] = 1;
Fill (i+1, j);
Fill(i-1, j);
Fill (i, j+1);
Fill (i, j - 1);
}
}

void CalculZerouri()
{
int i, j;
cntmax = 0;
for (i=1; i <= n; i++)
for (j = 1; j <= m; j++)
if (a[i][j] == 0)
{
cnt = 0;
Fill (i, j);
cntmax=max(cntmax,cnt);
}
ofstream fout("foto.out");
fout<<cntmax<<"\n";
fout.close();
}

int main()
{
Citire();
Bordare();
CalculZerouri();
return 0;
}

Numele problemei: pizza; Sursa: .campion 2007 /// PAGE 15


Link: http://campion.edu.ro/arhiva/index.php?page=problem&action=view&id=160

#include<iostream>
#include<fstream>
#include<string>
using namespace std;
ifstream fin("pizza.in");
ofstream fout("pizza.out");
int main ()
{
int i,n,x,y,k1,k2,k3,transport,r;
char x1,zero,y2;
in>>n; k1=0;k2=0;k3=0;
transport=0;
for (i=1;i<=n;i++)
{
fin>>x1; fin>>zero; fin>>y2;
x=x1-'0'; y=y2-'0';
if (x==1&&y==2)
k1++;
if (x==1&&y==4)
k2++;
if (x==3&&y==4)
k3++;
}
n=0;
if (k1%2==0) n=n+k1/2;
else
{ n=n+k1/2; transport=1; // ramane jumatate }

if (k2>k3) // au aparut k3 pizza si raman de grupat k2-k3 sferturi


{
if (transport==0)
{
n=n+k3;
r=(k2-k3)%4;
if (r==0) n=n+(k2-k3)/4;
else n=n+(k2-k3)/4+1;
}
if (transport==1)
{
n=n+k3;
r=(k2-k3)%4;
if (r==0) n=n+(k2-k3)/4+1;
else if (r==1 || r==2) n=n+(k2-k3)/4+1;
else n=n+(k2-k3)/4+2;
}
}

if (k2==k3)
{
n=n+k3;
if (transport==1)
n++;
}

if (k3>k2)
{
if (transport==0)
n=n+k3;
else
n=n+k3+1;
}
fout<<n<<"\n";
fin.close();
fout.close();
return 0;
}
Numele problemei: text; Sursa: OJI 2010; /// PAGE 16

Link: http://campion.edu.ro/arhiva/index.php?page=problem&action=view&id=1082

#include <fstream>
#include <cstring>
using namespace std;
char cuv[20001][22];
int d[20001], urm[20001], n;
int t[30];
// t[ch]=p: pozitia p in cuv a cuvantului care incepe cu litera // ch si care are d[p]
maxim
void Citire()
{
ifstream fin ("text3.in");
n=1;
while (fin>>cuv[n])
n++;
n--;
fin.close();
}
void LIS()
{
int i, maxim, poz, j, p;
char ch;
d[n] = 1;
urm[n] = n+1;
p = cuv[n][0] - 'a';
t[p] = n;
for (i = n - 1; i >= 1; i--)
{
ch = cuv[i][strlen(cuv[i]) - 1];
maxim = 0;
j = ch - 'a';
poz = t[j];
if (poz == 0) {d[i] = 1; urm[i] = n + 1;}
else { d[i] = 1 + d[poz]; urm[i] = poz; }
j = cuv[i][0] - 'a';
if (d[i] > d[t[j]]) t[j] = i;
}
}
void Afisare()
{
int i, m, poz;
ofstream fout("text3.out");
fout << n << "\n";
m = d[1]; poz = 1;
for (i = 2; i <= n; i++)
if (d[i] > m) {m = d[i]; poz = i;}
fout << (n - m) << "\n";
while (poz != n + 1)
{
fout << cuv[poz] << "\n";
poz = urm[poz];
}
fout.close();}
int main()
{
Citire();
LIS();
Afisare();
return 0;
}
Numele problemei: dir; Sursa: OJI 2007; /// PAGE 17
Link: http://campion.edu.ro/arhiva/index.php?page=problem&action=view&id=839

#include<fstream>
#include<algorithm>
#include<cstring>
using namespace std;

char s[1605], st[1002][35], f[102][260];


int n;
void SortareLexico()
{
int i,j;
char aux[260];
for (i=1;i<=n;i++)
{
for (j=1;j<=n;j++)
{
if (strcmp(f[j],f[i]) > 0)
/// se face interschimbare
{
strcpy (aux, f[i]);
strcpy (f[i],f[j]);
strcpy (f[j], aux);
}
}
}
}
void Afisare()
{
int i;
ofstream fout("dir.out");
fout<<n<<"\n";
for (i=1;i<=n;i++)
fout<<f[i]<<"\n";
/// lets count
fout.close();
}

int main()
{
int top, k, i,j;
char folder[35];
char fisier[35];
char cale[260];
ifstream fin("dir.in");
fin >> s;
top = 0;
for (i = 0; s[i] != 0; )
{
if ('A'<= s[i] && s[i] <= 'Z')
{
k = 0;
while (s[i] != 0 && s[i] != ')' && s[i] != '(' && s[i] !=
',')
{
folder[k++] = s[i];
i++;
}
folder[k] = 0;
top++;
strcpy(st[top],folder);
}
else if ('a'<= s[i] && s[i] <= 'z') /// PAGE 18

{
k = 0;
while (s[i] != 0 && s[i] != ')' && s[i] != '(' && s[i] !=
',')
{
fisier[k++] = s[i];
i++;
}
fisier[k] = 0;
//st=F1, F2, F3
strcpy(cale,st[1]);
strcat(cale,"\\");
for (j = 2;j<=top; j++)
{
strcat(cale,st[j]);
strcat(cale,"\\");
}
strcat(cale,fisier);
n++;
strcpy(f[n],cale);
}
else if (s[i] == '(') i++;
else if (s[i] == ',') i++;
else if (s[i] == ')')
{
i++;
top--;
}
}
SortareLexico();
Afisare();
/// f=matricea care retine totu bine
/// hai sa o sortam
return 0;
}
////////////////////////////////////////////////////////////////////////////////////

Numele problemei: vistiernic; Sursa: OMI Iasi 2013


Link: http://campion.edu.ro/arhiva/index.php?page=problem&action=view&id=1487

#include<fstream>
using namespace std;
ifstream fin("vistiernic.in");
ofstream fout("vistiernic.out");
int main()
{
int n,k,i,nr,t;
fin>>n;k =0; t=0;
for(i=1;i<=n;i++)
{ fin>>nr;
while((nr%5==0)||(nr%2==0))
{if(nr%5==0)
{ nr=nr/5; k++; }
if(nr%2==0)
{ nr=nr/2; t++; } }
}
if(t>=k) fout<<k;
else fout<<t;
fin.close();
fout.close(); return 0; }
Numele problemei: parantezare; Sursa: FMI No Stress 2012 /// PAGE 19
Link: http://www.infoarena.ro/problema/parantezare

#include <iostream>
#include <fstream>
#include <stdio.h>
#include <string.h>
using namespace std;
int n,vect[100005],aux,q[100005],i,j,k,aux2,len,cnt,cap;
char a[100005];
ifstream fin("parantezare.in");
ofstream fout("parantezare.out");
void Citire()
{
    fin>>a; fin>>n;
}
 
void Afisare()
{
    for (i=1;i<=n;i++)
{   in>>aux2;
    fout<<q[aux2]<<" ";
}   fin.close();
    fout.close();
}
 
void Rezolva ()
{
    len=strlen(a);
    cap=0;
    for (i=0;i<=len-1;i++)
    {
        if (a[i]=='(')
        {
            vect[++cap]=i;
        }
        else if (a[i]==')')
        {
            aux=vect[cap];
            q[aux]=i;
            cap--;
        }
    }
}
 
int main()
{
    Citire();
    Rezolva();
    Afisare();
return 0;
}

Numele problemei: muzeu; Sursa: Happy Coding 1 /// PAGE 20


Link: http://www.infoarena.ro/problema/muzeu

#include <fstream>
#include <queue>
 
using namespace std;
 
struct coord
{
    int x,y;
};
 
queue <coord> q;
char a[255][255];
int b[254][254], n;
 
void Citire()
{
    ifstream fin("muzeu.in");
    int i;
    fin>>n;
    fin.get();
        for (i=1;i<=n;i++)
        fin.getline(a[i]+1, 252);
    fin.close();
}
 
void Bordare()
{
    int i;
    for (i=0; i<=n+1; i++)
        a[i][0]=a[0][i]=a[n+1][i]=a[i][n+1]='#';
 
}
 
void Lee()
{
    int i,j;
    coord w, w1;
    int dx[]={1,0,-1,0};
    int dy[]={0,1,0,-1};
 
 for (i=1;i<=n;i++)
        for (j=1;j<=n;j++)
        if (a[i][j] == '#') b[i][j] = -2;
        else if (a[i][j] == '.') b[i][j] = -1;
        else // a[i][j] == 'P'
        {
                    b[i][j]=0;
            w.x = i; w.y = j;
            q.push(w);
        }
 
    while (!q.empty())
    {
        w = q.front();
        q.pop(); /// PAGE 21
        for (i=0;i<4;i++)
        {
           w1.x=w.x+dx[i];
           w1.y=w.y+dy[i];
           if (a[w1.x][w1.y] != '#' && (b[w1.x][w1.y] > b[w.x][w.y]+ 1 ||
b[w1.x][w1.y] == -1))
           {
                b[w1.x][w1.y] = b[w.x][w.y]+ 1;
                q.push(w1);
           }
        }
    }
}
 
void Afisare()
{
    ofstream out("muzeu.out");
    int i,j;
    for (i=1;i<=n;i++)
    {   for (j=1;j<=n;j++)
        {
             out<<b[i][j]<<" ";
        }
        out<<"\n";
    }
    out.close();
}
 
int main ()
{
    Citire();
    Bordare();
    Lee();
    Afisare();
    return 0;
}

/////////////////////////////////////////////////////////////////////////////////////

Numele problemei: palindrom; Sursa: Grigore Moisil 2009 – Clasele 5-8

Link: http://www.infoarena.ro/problema/palindrom2
 Se consideră un şir de caractere format din litere mici ale alfabetului englez. Transformaţi
şirul într-un palindrom de lungime minimă prin inserarea de caractere doar la sfârşitul şirului.
Lungimea şirului este cel mult 1 000.

Exemplu: aabac -> aabacabaa;

#include<fstream>
#include<cstring>
#include<iostream>
using namespace std;

ifstream fin ("palindrom2.in");


ofstream fout ("palindrom2.out");
 
int main () /// PAGE 22
{
int n,i,j,st,dr;
int ok,gasit;
char s[1000];
 
fin>>s;
n=strlen(s);
gasit=0;
for (i=0;i<n && gasit==0;i++)
{
    st=i;dr=n-1;
    ok=1;
    while (st<=dr && ok==1)
  {
   if (s[st]==s[dr])
      { st++; dr--; }
   else
     ok=0;
   }
 
   if (ok==1) gasit=1;
}
   fout<<s;
   for (j=i-2;j>=0;j--)
        fout<<s[j];
  fout<<"\n";
  fin.close();
  fout.close();
  return 0;
}

/////////////////////////////////////////////////////////////////////////////////////

Numele problemei: lacusta; Sursa: OJI 2005 – Clasa a X a

Link: http://www.infoarena.ro/problema/lacusta

Se considera o matrice dreptunghiulara cu m linii si n coloane, cu valori naturale. Traversam matricea


pornind de la coltul stanga-sus la coltul dreapta-jos. O traversare consta in mai multe deplasari. La
fiecare deplasare se executa un salt pe orizontala si un pas pe verticala. Un salt inseamna ca putem
trece de la o celula la oricare alta aflata pe aceeasi linie, iar un pas inseamna ca putem trece de la o
celula la celula aflata imediat sub ea. Exceptie face ultima deplasare (cea in care ne aflam pe ultima
linie), cand vom face doar un salt pentru a ajunge in coltul dreapta-jos, dar nu vom mai face si pasul
corespunzator. Astfel traversarea va consta din vizitarea a 2m celule. Scrieti un program care sa
determine suma minima care se poate obtine pentru o astfel de traversare.

Exemplu: Pentru n,m si matricea de mai jos, se va afisa drumul de suma minima 28.
4 5
3 4 5 7 9
6 6 3 4 4
6 3 3 9 6
6 5 3 8 2

#include<fstream>
#include<algorithm>
#include<cstring>
using namespace std; /// PAGE 23
short a[260][260];
int L, C, b1[260], b2[260];
 
inline void Citire()
{
    int i,j;
    ifstream fin ("lacusta.in");
    fin>>L>>C;
    for (i=1;i<=L;i++)
    {
        for (j=1;j<=C;j++)
            fin>>a[i][j];
    }
    fin.close();
}
 
 
inline void Calculeaza()
{
   ofstream fout("lacusta.out");
   int i, j, minim, k;
   b1[1]=100000;
   for (j=2;j<=C;j++)
   b1[j]=(int)a[1][1]+a[1][j]+a[2][j];
 
   for (i=3;i<=L;i++)
   {
       for (j=1;j<=C;j++)
       {
           minim=1000000;
           for (k=1;k<=C;k++)
              if (k!=j)
                  minim=min(b1[k],minim);
           b2[j]=minim+a[i][j]+a[i-1][j];
       }
 
     for (j=1;j<=C;j++)
        b1[j]= b2[j];
   }
 
   minim=100000;
   for (j=1;j<=C-1;j++)
     minim=min(b1[j],minim);
minim+=a[L][C];
 
fout<<minim<<"\n";
fout.close();
}
int main ()
{
    Citire();
    Calculeaza();
    return 0;
}
Numele problemei: sudest; Sursa: OJI 2006 – Clasa a X a /// PAGE 24

Link: http://www.infoarena.ro/problema/sudest

Fermierul Ion detine un teren de forma patrata, impartit in NxN patrate de latura unitate, pe care cultiva cartofi.
Pentru recoltarea cartofilor fermierul foloseate un robot special proiectat in acest scop. Robotul porneste din
patratul din stanga sus, de coordonate (1,1) si trebuie sa ajunga in patratul din dreapta jos, de coordonate (N,N).
Traseul robotului este programat prin memorarea unor comenzi pe o cartela magnetica. Fiecare comanda specifica
directia de deplasare (sud sau est) si numarul de patrate pe care le parcurge in directia respectiva. Robotul strange
recolta doar din patratele in care se opreste intre doua comenzi. Din pacate, cartela pe care se afla programul s-a
deteriorat si unitatea de citire a robotului nu mai poate distinge directia de deplasare, ci numai numarul de pasi pe
care trebuie sa-i faca robotul la fiecare comanda. Fermierul Ion trebuie sa introduca manual, pentru fiecare
comanda, directia de deplasare. Scrieti un program care sa determine cantitatea maxima de cartofi pe care o poate
culege robotul, in ipoteza in care Ion specifica manual, pentru fiecare comanda, directia urmata de robot. Se va
determina si traseul pe care se obtine la recolta maxima.

#include <fstream>
#include <queue>
 
using namespace std;
 
struct coord
{
    int x, y, nr;
    // nr retine la al catelea pas am ajuns acolo
};
 
queue <coord> q;
int a[105][105], b[105][105], n, tx[205],ty[205];
int c[205],k;
 
void Citire()
{
  int i, j;
  ifstream fin("sudest.in");
  fin>>n;
  for (i=1;i<=n;i++)
  for (j=1;j<=n;j++)
  fin>>a[i][j];
 
  fin>>k;
  for (i=1;i<=k;i++)
  fin>>c[i];
  fin.close();
}
 
inline int Interior(int i, int j)
{
    if (i > n) return 0;
    if (j > n) return 0;
    return 1;
}
 
void Lee()
{
    int i, pas;
    coord w, w1;
    int dx[]={1,0};
    int dy[]={0,1}; /// PAGE 25
    w.x=1;
    w.y=1;
    w.nr = 1;
    b[1][1] = a[1][1];
    q.push(w);
    while (!q.empty())
    {
        w=q.front();
          q.pop();
        pas = c[w.nr];
          for (i=0;i<2;i++)
         {
           w1.x=w.x+dx[i]*pas;
           w1.y=w.y+dy[i]*pas;
           w1.nr=w.nr+1;
        if (Interior(w1.x,w1.y) && b[w1.x][w1.y] < b[w.x][w.y] + a[w1.x]
[w1.y])
           {
                b[w1.x][w1.y] = b[w.x][w.y]+ a[w1.x][w1.y];
                if (w1.x * w1.y != n*n) q.push(w1);
           }
 
         }
}
}
 
void Afisare()
{
    ofstream fout("sudest.out");
    fout << b[n][n] << "\n";
    int i, j, p, pas;
    i = j = n;
    tx[k+1] = ty[k+1] = n;
    for (p = k; p >= 1; p--)
    {
        pas = c[p];
        if (i-pas < 1) j = j - pas;
        else if (j - pas < 1) i = i - pas;
        else if (b[i-pas][j] > b[i][j-pas])
            i = i - pas;
        else j = j - pas;
        tx[p] = i;
        ty[p] = j;
}
for (i = 1; i <= k + 1; i++)
    fout << tx[i] << " " << ty[i] << "\n";
    fout.close();
}
 
int main()
{
    Citire();
    Lee();
    Afisare();
    return 0;
}
Numele problemei: padure; Sursa: Stelele Informaticii 2006, clasele 9-10 /// PAGE 26
Link: http://www.infoarena.ro/problema/padure

Daca va intrebati ce mai face printul Algorel, acum puteti afla. El se afla pierdut undeva prin Padurea Magica si
cauta cu disperare drumul inapoi spre castelul sau. Padurea Magica poate fi reprezentata ca o matrice cu N linii
si M coloane, pentru fiecare celula din padure stiindu-se tipul copacilor care o acopera (numar natural mai mic
decat 104). O celula este acoperita numai cu copaci de acelasi tip. Printul Algorel se afla undeva in celula (pl,
pc) (pl reprezinta linia, pc coloana) iar castelul se afla situat in celula (cl, cc). Printul Algorel se poate deplasa in
cele patru directii: Nord, Sud, Est si Vest, dar nu poate sa iasa din padure fiindca dincolo de padure e taramul
Spanului cel Rau. In drumul sau catre castel, el trebuie sa plateasca Paduralului Magician un diamant pentru fiecare
trecere dintr-o celula in alta in care se schimba tipul copacilor (adica daca cele doua celule sunt acoperite cu tipuri
diferite de copaci). Pentru trecerile intre celule acoperite de acelasi tip de copaci el nu plateste nimic. Cum
diamantele sunt resursa cea mai importanta in regat, el vrea sa stie numarul minim de diamante pe care trebuie
sa-l plateasca pentru a ajunge la castel. Prima linie a fisierului padure.in se afla 6 numere
naturale N M pl pc cl cc, cu semnificatia de mai sus. Urmatoarele N linii contin cate M numere naturale separate
prin spatii, reprezentand tipul copacilor care acopera fiecare celula din Padurea Magica.
Fisierul de iesire padure.out trebuie sa contina pe prima linie un singur numar intreg D reprezentand numarul
minim de diamante pe care Algorel este nevoit sa-l plateasca pentru a ajunge la castel.

#include<fstream>
#include<queue>
using namespace std;
int a[1003][1003],b[1003][1003];
int xs,xf,ys,yf,n,m;
 
struct coord
{ int x,y;
};
queue <coord> q;
 
void Citire()
{ int i,j;
  ifstream fin("padure.in");
  fin>>n>>m>>xs>>ys>>xf>>yf;
  for (i=1;i<=n;i++)
  for (j=1;j<=m;j++)
  fin>>a[i][j];
  fin.close();
}
void Bordare()
{ int i;
  for (i=0;i<=m+1;i++) a[0][i]=a[n+1][i]=-1;
  for (i=0;i<=n+1;i++) a[i][0]=a[i][m+1]=-1;
}
void Lee()
{
  int i,cost;
  int dx[]={1,0,-1,0};
  int dy[]={0,1,0,-1};
  coord w,w1;
  w.x=xs;
  w.y=ys;
  b[w.x][w.y]=1;
  q.push(w);
  while (!q.empty())
  {
     w=q.front();
     q.pop();
     for (i=0;i<4;i++) /// PAGE 27
    {
       w1.x=w.x+dx[i];
       w1.y=w.y+dy[i];
      cost = 0;
      if (a[w1.x][w1.y] != a[w.x][w.y]) cost = 1;
       if (a[w1.x][w1.y]!=-1 && ( b[w1.x][w1.y] > b[w.x][w.y] + cost  ||
b[w1.x][w1.y]==0  ))
  {   b[w1.x][w1.y] = b[w.x][w.y] + cost ;
      q.push(w1);
  }
    }
  }
}
 

void Afisare()
{ ofstream fout("padure.out");
  fout<<(b[xf][yf]-1)<<"\n";
  fout.close();
}
 
int main ()
{ Citire();
  Bordare();
  Lee();
  Afisare();
  return 0;
}

///////////////////////////////////////////////////////////////////////////////////////////

Numele problemei: par; Sursa: Algoritmiada 2009, Runda 3

Link: http://www.infoarena.ro/problema/par

Ioana tocmai a invatat la scoala despre paranteze rotunde si despre siruri parantezate corect. Un sir
este parantezat corect daca este construit conform regulilor:

 <sir parantezat corect> = <sirul vid>


 <sir parantezat corect> = "(" + <sir parantezat corect> + ")"
 <sir parantezat corect> = <sir parantezat corect> + <sir parantezat corect>

Fişierul de intrare par.in contine pe prima linie numarul natural N, avand semnificatia din enunt. Pe a
doua linie urmeaza N caractere reprezentand sirul de paranteze furnizat de Andrei.

În fişierul de ieşire par.out se va afisa un singur numar, reprezentand numarul minim de inversari ce


trebuie efectuat pentru ca la sfarsit sirul sa fie corect parantezat. In cazul in care nu exista solutie se
va afisa doar numarul -1.

#include<fstream>
#include <stdio.h>
#include <string.h>
#include <algorithm>

using namespace std; /// PAGE 28


int n, i, dif, cnt;
char a[5005];
ifstream fin("par.in");
ofstream fout("par.out");
 
int main()
{
    in>>n;
    if (n%2==1)
    { fout<<"-1\n";
fout.close();
return 0;
}
    
fin>>a;
    cnt=0; dif=0;
    for (i=0;i<n;i++)
{
    if (a[i]=='(')
        dif++;
    else
    {
        dif--;
     if (dif<0) { cnt++; dif = 1;}
 
    }
}

cnt += (dif / 2);


fout<<cnt<<"\n";
fin.close();
fout.close();
return 0;
}
//////////////////////////////////////////////////////////////////////////////////

Numele problemei: betasah; Sursa: OJI 2013

Link: http://campion.edu.ro/arhiva/index.php?page=problem&action=view&id=1503

Jocul betaşah se joacă folosindu-se doar piese asemănătoare damelor clasicului şah, numite tot dame. Suprafaţa de joc are o
formă triunghiulară şi este formată din N(N+1)/2 pătrate identice dispuse pe N rânduri şi N coloane. Rândurile se numerotează de
sus în jos, de la 1 la N. Coloanele se numerotează de la stânga la dreapta, de la 1 la N. Primul rând conţine un singur pătrat, al
doilea rând conţine două pătrate alăturate,..., al N-lea rând conţine N pătrate alăturate, ca în suprafeţele de joc cu N=6 din figurile de
mai jos. Din cele N(N+1)/2 pătrate, K sunt gri, iar restul sunt albe. Poziţia fiecărui pătrat de pe suprafaţa de joc este dată de rândul
şi coloana în care acesta este situat. Pe suprafaţa de joc sunt aşezate D dame în D pătrate albe distincte, ocupându-le. Într-un
pătrat alb poate fi aşezată o singură damă, iar într-un pătrat gri nu poate fi aşezată nicio damă. Poziţia unei dame pe suprafaţa de
joc este dată de poziţia pătratului alb în care este aşezată dama.
Damele pot accesa orice pătrat alb neocupat situat pe direcţiile: verticală, orizontală sau diagonală, numerotate de la 1 la 8 în figura
b). Accesul pe o direcţie se face trecând din pătrat alb în pătrat alb (doar pătrate albe neocupate) până la întâlnirea unui pătrat gri
sau a unui pătrat alb ocupat de o altă damă sau până la terminarea suprafeţei de joc. 
Numim pătrat accesibil orice pătrat alb neocupat (de pe suprafaţa de joc) care ar putea fi accesat de cel puţin una din cele D dame. 
De exemplu, pentru suprafaţa de joc din figura c) numărul de pătrate accesibile (marcate cu X) de pe suprafaţă este 11; pentru
suprafaţa de joc cu N=6, D=3 şi K=4 din figura d) numărul de pătrate accesibile de pe suprafaţă este 13. În figura e) sunt marcate cu
X pătraţele accesibile fiecărei dame de pe suprafaţa de joc din figura d). Scrieţi un program care să citească numerele naturale N D
K, poziţiile damelor şi ale pătratelor gri pe suprafaţa de joc şi care să determine: 
a) numărul maxim M de pătrate albe conţinute de un rând al suprafeţei de joc; /// PAGE 29
b) numărul P de pătrate accesibile de pe suprafaţa de joc.

Fişierul de intrare betasah.in conţine: 
- pe prima linie cele trei numere naturale N D K, separate prin câte un spaţiu, cu semnificaţia din enunţ; 
- pe linia i+1 două numere naturale nenule xi yi, separate printr-un singur spaţiu, reprezentând poziţia damei i pe suprafaţa de
joc (rândul xi şi coloana yi), pentru i=1,2,3,…,D;
- pe linia D+1+j două numere naturale nenule zj tj, separate printr-un singur spaţiu, reprezentând poziţia pătratului gri j pe
suprafaţa de joc (rândul zj şi coloana tj), pentru j=1,2,3,…,K.

Fişierul de ieşire betasah.out va conţine pe prima linie numărul natural M şi pe a doua linie numărul natural P, cu semnificaţia din
enunţ.

#include<fstream>
#include <stdio.h>
#include <string.h>
#include <time.h>
using namespace std;
int a[1004][1004],n,d,k,i,L,C,x[130],y[130],maxim,cnt,nt,j;
int aux1,aux2;
void Citire()
{
ifstream fin("betasah.in");
in>>n>>d>>k;
for (i=1;i<=d;i++)
{
in>>L>>C;
y[i]=L;x[i]=C;
a[L][C]=69;
}
for (i=1;i<=k;i++)
{
in>>L>>C;
a[L][C]=1;
}
maxim=-1;
for (i=1;i<=n;i++)
{ nt=0;
for (j=1;j<=i;j++)
{
if (a[i][j]==0||a[i][j]==69) nt++;
}
if (maxim<nt) maxim=nt;
}
fin.close();
}

void Rezolva1() // sets the limits of the matrice


{
a[0][0]=1;
a[n+1][0]=1;
a[n+1][n+1]=1;
for (i=1;i<=n;i++)
{ a[i][i+1]=1;
a[i][0]=1;
a[n+1][i]=1;
}
for (i=0;i<=n+1;i++)
{
for (j=i+1;j<=n+1;j++)
a[i][j]=1;
}
} /// PAGE 30

void Rezolva2()
{
///end that shift
cnt=0;
for (i=1;i<=d;i++)
{
///NORD
aux1=y[i]; aux2=x[i]; aux1--;
while (a[aux1][aux2]!=1&&a[aux1][aux2]!=69)
{
if (a[aux1][aux2]==0) cnt++;
a[aux1][aux2]=2;
aux1--;
}

///SUD
aux1=y[i]; aux2=x[i]; aux1++;
while (a[aux1][aux2]!=1&&a[aux1][aux2]!=69)
{
if (a[aux1][aux2]==0) cnt++;
a[aux1][aux2]=2;
aux1++;
}

///EST
aux1=y[i]; aux2=x[i]; aux2++;
while (a[aux1][aux2]!=1&&a[aux1][aux2]!=69)
{
if (a[aux1][aux2]==0) cnt++;
a[aux1][aux2]=2;
aux2++;
}

///VEST
aux1=y[i]; aux2=x[i]; aux2--;
while (a[aux1][aux2]!=1&&a[aux1][aux2]!=69)
{
if (a[aux1][aux2]==0) cnt++;
a[aux1][aux2]=2;
aux2--;
}

///NE
aux1=y[i]; aux2=x[i]; aux1--; aux2++;
while (a[aux1][aux2]!=1&&a[aux1][aux2]!=69)
{
if (a[aux1][aux2]==0) cnt++;
a[aux1][aux2]=2;
aux1--; aux2++;
}

///NV
aux1=y[i]; aux2=x[i]; aux1--; aux2--;
while (a[aux1][aux2]!=1&&a[aux1][aux2]!=69)
{
if (a[aux1][aux2]==0) cnt++;
a[aux1][aux2]=2;
aux1--; aux2--;
}
///SE
aux1=y[i]; aux2=x[i]; aux1++; aux2++; /// PAGE 31
while (a[aux1][aux2]!=1&&a[aux1][aux2]!=69)
{
if (a[aux1][aux2]==0) cnt++;
a[aux1][aux2]=2;
aux1++; aux2++;
}

///SV
aux1=y[i]; aux2=x[i]; aux1++; aux2--;
while (a[aux1][aux2]!=1&&a[aux1][aux2]!=69)
{
if (a[aux1][aux2]==0) cnt++;
a[aux1][aux2]=2;
aux1++; aux2--;
}

}
}

void Afisare()
{
ofstream fout("betasah.out");
fout<<maxim<<"\n"<<cnt;
fout.close();
}

int main()
{
Citire();
Rezolva1();
Rezolva2();
Afisare();
return 0;
}

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