Documente Academic
Documente Profesional
Documente Cultură
Obiective:
Secvențe de lungime maximă
Prelucrarea sevențelor Prima/ultima/toate secvențele de
lungime maximă
Identificarea situațiilor în care trebuie
utilizate
Aplicarea și modificarea algoritmului
pentru rezolvarea problemelor
Cuprins:
Rezolvarea temei ..................................................................................................................................... 2
Problema #244 .................................................................................................................................... 2
Problema #2177 .................................................................................................................................. 2
Problema #1145 .................................................................................................................................. 3
Problema #2296 .................................................................................................................................. 4
Problema #239 .................................................................................................................................... 5
Problema #267 .................................................................................................................................... 5
Problema #525 .................................................................................................................................... 6
Problema #264 .................................................................................................................................... 7
Problema #1005 .................................................................................................................................. 7
Problema #1061 .................................................................................................................................. 7
Problema #528 rămâne în continuare TEMĂ .................................................................................... 10
Secvențe de lungime Maximă ............................................................................................................... 10
Definiție - secvență ............................................................................................................................ 10
Definiție- lungimea unei secvențe..................................................................................................... 10
Algoritm ............................................................................................................................................. 10
Temă: ..................................................................................................................................................... 11
#166, #516, #304, #283, #181, #518, #523, #190 #298, #300 ......................................................... 11
Suplimentar: #1804, #1121 ............................................................................................................... 11
Prof. Mihaela Corina ILDEGEZ
Centru pentru pregătire pentru Performanță
Rezolvarea temei
Problema #244
#include <fstream>
using namespace std;
ifstream f("cifreord.in");
ofstream g("cifreord.out");
int main()
{
int x, fr[10]= {0},n;
f>>n;
for(int i=1; i<=n; i++)
{
f>>x;
fr[x]++;
}
x=0;
for(int i=0; i<=9; i++)
{
///daca exista cifra i trebuie afisate de fr[i] ori
if(fr[i])
for(int j=1; j<=fr[i]; j++)
{
g<<i<<" ";
x++;
if(x%20==0)
g<<endl;
}
}
return 0;
}
Problema #2177
#include <fstream>
using namespace std;
ifstream f("cod3.in");
ofstream g("cod3.out");
int main()
{
int fr[100]={0},n,x;
f>>n;
for(int i=1;i<=n;i++)
{
f>>x;
fr[x]++;
}
for(int i=0;i<100;i++)
if(fr[i])
if(fr[i]%2!=0)
g<<i;
return 0;}
Prof. Mihaela Corina ILDEGEZ
Centru pentru pregătire pentru Performanță
Problema #1145
#include <bits/stdc++.h>
using namespace std;
ifstream f("extraprime.in");
ofstream g("extraprime.out");
void Ciur()
{
///fac ciur pentru numere prime;
ciur[1]=1;
for(int i=4; i<=nmax-5; i+=2)
ciur[i]=1;
for(int i=3; i*i<=nmax-5; i+=2)
if(!(ciur[i]))
for(int j=i*i; j<=nmax-5; j+=2*i)
ciur[j]=1;
}
bool Solve(int x)
{
ncif=0;
if(ciur[x])
return false;
while(x)
{
cif[++ncif]=x%10;
x/=10;
}
for(int i=ncif;i>=1;i--)
///pornesc de la sf vectorului deoarece acolo se afla prima cifra a numarului
{
///elimin cifra de pe pozitia i.
int x=0;
for(int j=ncif;j>=1;j--)
if(i!=j)
x=x*10+cif[j];
if(ciur[x]) ///nu este numar prim
return false;
}
return true;
}
int main()
{
int s=0;
Ciur();
f>>a>>b;
int mx=-LONG_MAX,mn=LONG_MAX;
for(int i=a;i<=b;i++)
{
int nr=i;
Prof. Mihaela Corina ILDEGEZ
Centru pentru pregătire pentru Performanță
if(Solve(nr))
{
mx=max(mx,nr);
s++;
mn=min(mn,nr);
}
}
g<<s<<"\n";
g<<mn<<"\n";
g<<mx<<"\n";
return 0;
}
Problema #2296
Observăm că valorile relativ mici ale elementelor șirurilor ne permite reținerea acestora în doi vectori,
astfel:
cntA[i] – de câte ori apare elementul i în primul șir
cntB[i] – de câte ori apare elementul i în al doilea șir
Cu o variabilă d vom itera peste toate valorile posibile ale celui mai mare divizor comun (de la 1 000
000 la 1), astfel încât în cei doi vectori creați anterior vom căuta multipli ai lui d, care vor fi de forma i * d,
cu i de la 1 la (1 000 000 / d). Această abordare obține punctaj maxim.
#include <fstream>
using namespace std;
bool a[1000001], b[1000001];
int n, v;
int main()
{
int i, j, mx=1, x, ok1, ok2;
ifstream f("gcd.in");
ofstream g("gcd.out");
f>>n;
if(ok1*ok2)
mx=i;
}
g<<mx;
return 0;
}
Problema #239
#include <fstream>
using namespace std;
ifstream f("nrlipsa.in");
ofstream g("nrlipsa.out");
int main()
{
int fr[1000]={0};
int x;
while(f>>x)
if(x>=100 and x<1000)
fr[x]=1;
x=999;
while(x>=100 and fr[x]==1)
x--;
if(x>=100)
{
int y=x-1;
while(y>=0 and fr[y]==1)
y--;
if(y>=100)
g<<x<<" "<<y;
else
g<<"NU";
}
else
g<<"NU";
return 0;
}
Problema #267
#include <fstream>
using namespace std;
ifstream f("unice.in");
ofstream g("unice.out");
int main()
{
int fr[100]={0};
int n,x;
f>>n;
for(int i=1;i<=n;i++)
{
f>>x;
fr[x]++;
}
Prof. Mihaela Corina ILDEGEZ
Centru pentru pregătire pentru Performanță
for(int i=0;i<100;i++)
if(fr[i]==1)
g<<i<<" ";
return 0;
}
Problema #525
#include <iostream>
using namespace std;
int main()
{
int fr[1000]={0};
int n,x;
cin>>n;
for(int i=1;i<=n;i++)
{ cin>>x;
if(x>=100 and x<1000)
fr[x]=1;
}
x=999;
while(x>=100 and fr[x]==1) ///cel mai mare nr. care nu exista
x--;
if(x>=100)
{
int y=x-1;
while(y>=0 and fr[y]==1)
y--;
if(y>=100)
cout<<y<<" "<<x;
else
cout<<"NU EXISTA";
}
else
cout<<"NU EXISTA";
return 0;
}
Problema #2702
#include <iostream>
using namespace std;
int main()
{ int fr[101]={0};
int n,x;
cin>>n;
for(int i=1;i<=n;i++)
{ cin>>x;
fr[x]++;
}
int nr=0;
for(int i=1;i<=100;i++)
if(fr[i]!=0)
nr=nr+fr[i]/2;
cout<<nr;
return 0;
}
Prof. Mihaela Corina ILDEGEZ
Centru pentru pregătire pentru Performanță
Problema #264
#include <fstream>
using namespace std;
ifstream f("maxcif.in");
ofstream g("maxcif.out");
int main()
{
int x, fr[10]={0};
while(f>>x)
fr[x]++;
int maxx=0;
for(int i=0;i<=9;i++)
if(fr[i]>maxx)
maxx=fr[i];
for(int i=0;i<=9;i++)
if(fr[i]==maxx)
g<<i<<" ";
return 0;
}
Problema #1005
#include <fstream>
using namespace std;
ifstream f("numere8.in");
ofstream g("numere8.out");
int main()
{
bool fr[10000]={0};
int x;
while(f>>x)
if(x<10000)
fr[x]=1;
for(int i=9999;i>=1;i--)
if(fr[i]==0)
g<<i<<" ";
return 0;
}
Problema #1061
Vom utiliza tabloul unidimensional Apar, cu 10 elemente, care memorează de câte ori se repetă
fiecare cifră în cifrul inițial, deci:
Valorile tabloului Apar pot fi calculate pe măsură ce citim datele de intrare, nefiind nevoie de
memorarea celor N numere ce formează cifrul. Este suficient să aflăm câte discuri sunt poziționate inițial
pe cifra 0, câte pe cifra 1, …, câte pe cifra 9, iar apoi să calculăm numărul minim de mutări necesare
pentru a poziționa cifrul pe o anumită cifră. Astfel:
Calculăm pe rând, pentru fiecare cifră i= 0,1… 9 care apare măcar o dată în cifru, numărul de
mutări necesare pentru ca toate discurile cifrului să fie setate pe valoarea i, astfel:
(C++)
for(j=0;j<=9;j++)
if(Apar[j] && j!=i)
Prof. Mihaela Corina ILDEGEZ
Centru pentru pregătire pentru Performanță
if(abs(j-i) <= 10 - abs(j-i))
Nr= Apar[j]*abs(j-i);
else
Nr= Apar[j]*(10 - abs(j-i));
Se tine cont de faptul că fiecare disc poate fi mutat în două direcții deci, dacă cifrul este
poziționat pe cifra j, pentru a-l muta pe cifra i putem face abs(j-i) mutări în sus sau 10 – abs(j-i )
mutări în jos. La fiecare pas considerăm cea mai mică valoare dintre cele două.
Când găsim un număr total de mutări mai mic actualizăm minimul curent și reținem cifra pentru
care se obține acesta. Atunci când găsim un număr total de mutări egal cu minimul curent
incrementăm numărul de soluții de valoare minimă.
///Autor Cherteș Andrei clasa VI-a
#include <iostream>
#include <fstream>
using namespace std;
ifstream fin("cifru1.in");
ofstream fout("cifru1.out");
int main()
{
short int a[100001];
int i,n;
int b[10]={0},j;
int maxx=0;
int minn;
int nr=0;
bool gasit=false;
fin>>n;
for(i=1; i<=n; i++)
fin>>a[i];
for(i=1; i<=n; i++)
{
if(a[i]>maxx)
maxx=a[i];
}
fout<<maxx<<endl;
for(j=0; j<10; j++)
for(i=1; i<=n; i++)
{
if(a[i]<j)
{
if(a[i]+10-j<=j-a[i]) //Trecerea peste ordin
b[j]=b[j]+a[i]+10-j;
else
b[j]=b[j] +j-a[i];
}
else
{
if(j+10-a[i]<a[i]-j) //Trecerea peste ordin
b[j]=b[j]+j+10-a[i];
else
b[j]=b[j]+a[i]-j;
}
}
minn=b[0];
for(j=1;j<10;j++)
if(b[j]<minn)
minn=b[j];
fout<<minn<<endl;
for(j=0;j<10 && !gasit ;j++)
Prof. Mihaela Corina ILDEGEZ
Centru pentru pregătire pentru Performanță
if(b[j]==minn)
{
fout<<j<<endl;
gasit=true;
}
for(j=0;j<10;j++)
if(b[j]==minn)
nr++;
fout<<nr;
return 0;
}
int main()
{
ifstream IN(Fin);
ofstream OUT(Fou);
int N; //numarul discurilor
int Apar[10]; //Apar[i] = 1 daca culoarea i apare pe cel putin un disc
int MAX; //cifra maxima
int NrMin; //numarul minim de mutari
int Cif; //cifra obtinuta in numarul minim de mutari
int Cate; //numarul posibilitatilor
int i,j, Nr, x;
//initializari
for(i=0;i<=9;i++) Apar[i] = 0;
if(Nr<NrMin)
Prof. Mihaela Corina ILDEGEZ
Centru pentru pregătire pentru Performanță
NrMin = Nr, Cif = i, Cate = 1;
else
if(Nr==NrMin)
Cate++;
}
OUT<<MAX<<'\n'<<NrMin<<'\n'<<Cif<<'\n'<<Cate<<'\n';
IN.close();
OUT.close();
return 0;
}
Problema #528 rămâne în continuare TEMĂ
Exemplu: Fie vectorul X[]=(10, 20, 30, 40, 50, 60, 70, 80). Atunci:
(10, 20, 30, 40), (30, 40, 50, 60, 70), (10, 20, 30, 40, 50, 60, 70, 80), (50), (80) reprezintă
secvențe ale lui X
(10, 30, 40, 20) nu reprezintă secvență în X – ordinea valorilor nu este cea din X
(10,20,40,50) nu reprezintă secvență în X – valorile nu sunt consecutive în X
(10,20,30,35,40) nu reprezintă secvență în X – avem o valoare care nu apare în X
Definiție- lungimea unei secvențe: Prin lungimea unei secvențe se înțelege numărul de elemente
care formează secvența. Lungimea secvenței delimitate de indicii stg și drp este drp - stg + 1.
Fie X[] un vector cu elemente de un anumit tip. Să se determine cea mai lungă secvență din vector în care
toate elementele au o anumită proprietate (sunt pare, impare, prime, nule, ordonate crescător, egale
etc.).
Temă:
#166, #516, #304, #283, #181, #518, #523, #190 #298, #300
Suplimentar: #1804, #1121