Răspuns :
Sa pornim cu cel mai simplu caz posibil: suma termenilor din set este de fix 2017, iar suma este formata doar din 2 termeni. Sa ne uitam in conditiile date de problema daca asa ceva e posibil.
Spune ca borna ramasa de valoare maxima are minimum valoarea 1600. Acesta este si cazul cel mai defavorabil, deoarece daca borna maxima ar avea o valoare mai mare de 1600, ai putea sa folosesti drept al doilea termen o borna lipsa din intervalul 1-417. Asa, trebuie sa iei borne lipsa de la 418 in sus
Apoi, pot sa fie maximum 500 de borne ramase. Cel mai defavorabil caz ar fi daca am avea 500 de borne ramase. Dar chiar daca ar fi toate si ar fi masate fie in intervalul 1101-1600 fie in intervalul 418-918 tot ar ramane suficiente borne lipsa pentru a forma suma de 2017 din doar 2 elemente(cele din intervalul 918-2100). Deci pentru o singura solutie este suficient sa avem 2 termeni pentru fiecare drum.
Algoritmul necesar este cel de jos
#include <iostream>
#include <fstream>
using namespace std;
//initializam vectorul cu 0
int borne[2017];
int main(){
int n,nr_borne_ramase,borne_ramase[500],borna_max,i,ind_set,ind_borna,cauta_set;
ifstream fit("roadtooni.in");
ofstream fot("roadtooni.out");
fit>>n;
for(ind_set=0;ind_set<n;ind_set++){
fit>>nr_borne_ramase;
//borna maxima determinata in borna_max
borna_max=0;
for(i=0;i<nr_borne_ramase;i++){
fit>>borne_ramase[i];
//marcam in borne borna care a ramas cu 1
borne[borne_ramase[i]]=1;
if(borna_max<borne_ramase[i]){
borna_max=borne_ramase[i];
}
}
//stim de la inceput ca va fi un set din 2 borne
fot<<2<<" ";
//cat timp cauta_set este activ, adica 1
cauta_set=1;
//indicele de borna este cu 1 mai mic decat borna maxima ramasa
ind_borna=borna_max-1;
while(cauta_set==1){
//daca indicele bornei actuale si a celei pereche din suma
//sunt ambele 0, inseamna ca nu se regaseste printre cele ramase,
//deci am gasit o solutie
if(borne[ind_borna]==0&&borne[2017-ind_borna]==0){
cauta_set=0;
fot<<ind_borna<<" "<<2017-ind_borna<<endl;
}
//daca nu am gasit solutie, trecem la urmatoarea borna inferioara
ind_borna--;
}
//dupa ce am terminat verificarea pentru drumul i, reseteaza vectorul borne cu valori 0
//pentru a putea fi folosit la urmatorul drum
for(i=0;i<nr_borne_ramase;i++){
borne[borne_ramase[i]]=0;
}
}
return 0;
}
Spune ca borna ramasa de valoare maxima are minimum valoarea 1600. Acesta este si cazul cel mai defavorabil, deoarece daca borna maxima ar avea o valoare mai mare de 1600, ai putea sa folosesti drept al doilea termen o borna lipsa din intervalul 1-417. Asa, trebuie sa iei borne lipsa de la 418 in sus
Apoi, pot sa fie maximum 500 de borne ramase. Cel mai defavorabil caz ar fi daca am avea 500 de borne ramase. Dar chiar daca ar fi toate si ar fi masate fie in intervalul 1101-1600 fie in intervalul 418-918 tot ar ramane suficiente borne lipsa pentru a forma suma de 2017 din doar 2 elemente(cele din intervalul 918-2100). Deci pentru o singura solutie este suficient sa avem 2 termeni pentru fiecare drum.
Algoritmul necesar este cel de jos
#include <iostream>
#include <fstream>
using namespace std;
//initializam vectorul cu 0
int borne[2017];
int main(){
int n,nr_borne_ramase,borne_ramase[500],borna_max,i,ind_set,ind_borna,cauta_set;
ifstream fit("roadtooni.in");
ofstream fot("roadtooni.out");
fit>>n;
for(ind_set=0;ind_set<n;ind_set++){
fit>>nr_borne_ramase;
//borna maxima determinata in borna_max
borna_max=0;
for(i=0;i<nr_borne_ramase;i++){
fit>>borne_ramase[i];
//marcam in borne borna care a ramas cu 1
borne[borne_ramase[i]]=1;
if(borna_max<borne_ramase[i]){
borna_max=borne_ramase[i];
}
}
//stim de la inceput ca va fi un set din 2 borne
fot<<2<<" ";
//cat timp cauta_set este activ, adica 1
cauta_set=1;
//indicele de borna este cu 1 mai mic decat borna maxima ramasa
ind_borna=borna_max-1;
while(cauta_set==1){
//daca indicele bornei actuale si a celei pereche din suma
//sunt ambele 0, inseamna ca nu se regaseste printre cele ramase,
//deci am gasit o solutie
if(borne[ind_borna]==0&&borne[2017-ind_borna]==0){
cauta_set=0;
fot<<ind_borna<<" "<<2017-ind_borna<<endl;
}
//daca nu am gasit solutie, trecem la urmatoarea borna inferioara
ind_borna--;
}
//dupa ce am terminat verificarea pentru drumul i, reseteaza vectorul borne cu valori 0
//pentru a putea fi folosit la urmatorul drum
for(i=0;i<nr_borne_ramase;i++){
borne[borne_ramase[i]]=0;
}
}
return 0;
}
Vă mulțumim pentru vizita pe site-ul nostru dedicat Informatică. Sperăm că informațiile disponibile v-au fost utile și inspiraționale. Dacă aveți întrebări sau aveți nevoie de suport suplimentar, suntem aici pentru a vă ajuta. Ne face plăcere să vă revedem și vă invităm să adăugați site-ul nostru la favorite pentru acces rapid!