Gigel este un pasionat al triunghiurilor. El colectează beţişoare de diferite lungimi şi le asamblează în diferite triunghiuri. Ieri, el avea 6 beţişoare de lungimi 5, 2, 7, 3, 12
şi 3
. Din aceste bețișoare, Gigel a construit un triunghi de laturi 3, 3
şi 5
, iar beţişoarele de lungimi 2, 7, 12
au rămas nefolosite pentru că aceste lungimi nu pot forma laturile unui triunghi.
Din acest motiv, Gigel s-a hotărât să facă o colecţie de beţişoare, dintre care oricum ar alege 3
elemente, acestea să nu poată forma laturile unui triunghi, proprietate pe care o vom numi în continuare proprietate anti-triunghi. Gigel, pornind de la setul iniţial de lungimi 2, 7, 12,
s-a gândit la două metode de realizare a unei colecţii de 5
beţişoare cu proprietatea anti-triunghi, şi anume:
1.Păstrează cel mai scurt beţişor, cel de lungime 2
, şi creează un set nou adăugând alte beţişoare de lungime mai mare sau egală cu cel iniţial. De exemplu, următoarele 5
lungimi sunt corecte: 2, 2, 12, 50, 30
.
2.Păstrează toate beţişoarele, şi anume 2, 7,12,
pe care le va completa cu alte beţişoare de diferite lungimi (mai scurte sau mai lungi), astfel ca proprietatea anti-triunghi să se păstreze. Următoarele 5
lungimi respectă proprietatea anti-triunghi: 2, 7, 12, 4, 1.
Cerinţă
Cunoscând un şir de n
numere naturale nenule a
1
, a
2
, …, a
n
având proprietatea anti-triunghi, şi un număr k (k>n)
, se cere să construiţi un şir de k
numere naturale având proprietatea anti-triunghi, în conformitate cu una dintre următoarele două restricţii:
Varianta 1. Cel mai mic element este identic cu cel mai mic element din şirul iniţial.
Varianta 2. Printre cele k
elemente ale şirului construit se regăsesc toate elementele şirului iniţial.
Date de intrare
Fişierul de intrare triunghi2.in
conţine pe prima linie valorile numerelor v
, n
şi k
, separate prin spaţiu. Linia următoare conţine n
numere naturale separate prin spaţiu, ce formează un şir cu proprietatea anti-triunghi.
Date de ieşire
Fişierul de ieşire triunghi2.out
va conţine k
numere pe o singură linie.
Dacă valoarea lui v
este 1
, atunci fişierul va conţine k
numere naturale cu proprietatea anti-triunghi, separate prin spaţiu, în care cel mai mic element este identic cu minimul şirului dat în fişierul de intrare.
Dacă valoarea lui v
este 2
, atunci fişierul va conţine k
numere naturale cu proprietatea anti-triunghi, separate prin spaţiu, printre care se regăsesc toate elementele şirului iniţial.
Restricţii şi precizări
3 ≤ n < k ≤ 46;
1 ≤ lungimea unui beţişor ≤ 2.000.000.000;
- Pentru rezolvarea corectă a primei cerinţe se acordă
30
de puncte, iar pentru cerinţa a doua se acordă70
de puncte; - Se garantează că întotdeauna există soluţie;
- Soluţia nu este unică – se admite orice răspuns corect.
Exemple
triunghi2.in
1 3 5 7 2 12
triunghi2.out
2 2 30 50 12
triunghi2.in
2 3 5 7 2 12
triunghi2.out
1 4 12 7 2
Explicație
Pentru primul exemplu:
v=1, n=3, k=5
. În varianta 1
avem de tipărit 5
numere, valoarea minimului este 2
în ambele şiruri.
Pentru al doilea exemplu:
v=2, n=3, k=5
. În varianta 2
printre elementele şirului tipărit se regăsesc toate elementele şirului iniţial.
SOLUTIE 1
#include <fstream> using namespace std; int ok[50]; int main() { int pa,pb,a[50],n,k,i,j,b[50],aux,x,opt; ifstream fin("triunghi2.in"); ofstream fout("triunghi2.out"); fin>>opt>>n>>k; for (i=1;i<=n;i++) fin>>a[i]; for (i=1;i<n;++i) for (j=i+1;j<=n;++j) if (a[i]>a[j]) { aux=a[i]; a[i]=a[j]; a[j]=aux; } if (opt==1) { b[1]=b[2]=a[1]; for (i=3;i<=k;i++) b[i]=b[i-1]+b[i-2]; for (i=1;i<=k;++i) fout<<b[i]<<' '; fout<<"\n"; } else { if (a[1]==a[2]) { b[1]=b[2]=a[1]; ok[1]=ok[2]=1; //in sirul b bifam toate elementele pa=3; // ce apartin lui a } else { b[1]=b[2]=1; if (a[1]==1) // se bifeaza elementul 1 in cazul { ok[1]=1; // in care este element din a pa=2; } else pa=1; } pb=2; while (pa<n) { x=b[pb]+b[pb-1]; if (b[pb]+x<=a[pa] && x<=a[pa+1]-a[pa]) b[++pb]=x; else { b[++pb]=a[pa++]; ok[pb]=1; } } while (pa==n) { x=b[pb]+b[pb-1]; if(b[pb]<=a[pa]-x) b[++pb]=x; else { b[++pb]=a[pa++]; ok[pb]=1; } } while (b[pb]<=2000000000-b[pb-1]) { b[pb+1]=b[pb]+b[pb-1]; pb++; } for (i=1;i<=pb;i++) if (ok[i]) fout<<b[i]<<" "; x=k-n; for(i=1;x && i<=pb;i++) if (!ok[i]) { fout<<b[i]<<" "; --x; } fout<<"\n"; } fin.close(); fout.close(); return 0; }
SOLUTIE 2
#include <iostream> #include <fstream> using namespace std; ifstream f("triunghi2.in"); ofstream g("triunghi2.out"); int n,k,m,choise;//m-valoarea minima din vector int nr;//numarul de bete adaugate int v[50], u[50]; //v - initial, u-dupa adaugare void citire(){ int i; f>>choise>>n>>k; m=2000000000; for(i=1;i<=n;i++){ f>>v[i];//citesc betioasere si calculez valoarea minima if(v[i]<m) m=v[i]; u[i]=v[i];//pun toate betele in solutie pt. pct. b } } void solutie1(){ int b1,b2,b3; g<<m<<" "<<m<<" ";//afisez cel mai mic bat de doua ori nr=2;//am doua bete b1=b2=m; while(nr<k) {//cat timp nu am k bete adaugate b3=b2+b1;//calculez urmatoarea lungime cu care nu pot forma triunghi b1=b2;b2=b3;//trec la urmatoarele 2 bete g<<b2<<" ";//afisez lungimea noului bat nr++;//contabilizez batul } g<<"\n"; } void sortare(){//sortez betele initiale int i,j,aux; for(i=1;i<n;i++) for(j=i+1;j<=n;j++) if(v[i]>v[j]) {aux=v[i];v[i]=v[j];v[j]=aux;} } void solutie2(){ //incerc sa pun bete inainte de fiecare bat i cu i<-1,n int i,b1,b2,b3,j;//b1-penultimul bat pus, b2 - ultimul bat pus, b3 - noul bat care se adauga i=1;//incepand cu primul bat din stiva initiala nr=n;//am cele n bete initiale b1=0;//penultimul bat pus b2=1;//ultimul bat pus if(b1+b2+v[i]>v[i+1]){//daca adaug batul de lungime 1 pot depasi al doilea in cazul 2 2 5 7 b1=v[i];b2=v[i+1]; //atunci incep cu cele mai mici 2 bete } else {//altfel adaug batul de lungime 1 nr = nr + 1; u[nr]=1; } //incerc sa pun bete inainte de batul v[i] while(nr<k && i<=n) { //cat timp nu am pus k bete si mai sunt bete inainte carora pot pune b3=b2+b1;//incerc sa pun b3 if(b3+b2<=v[i]){//daca suma dintre ultimul bat adaugat si nnoul bat e ok nr++;//creste numarul de bete adaugate u[nr]=b3;//retin noul bat b1=b2;//penultimul bat b2=b3;//ultimul bat } else {//nu mai pot pune bete inainte de v[i] b1=b2;//penultimul bat adaugat b2=v[i];//ultimul bat i=i+1;//trec la urmatorul bat inaintea caruia incerc sa pun } } if(nr<k){//daca nu am pus toate betele inainte de betele initiale //pun bete dupa ultimul bat if(v[n-1]>u[nr])b1=v[n-1];//verific care e penultimul element else b1=u[nr]; b2=v[n]; while(nr<k) { b3=b2+b1; nr++; u[nr]=b3; b1=b2; b2=b3; } } for(i=1;i<=k;i++) g<<u[i]<<" "; } int main() { citire(); if(choise==1) solutie1(); else { sortare(); solutie2(); } return 0; }