Te-ai încuiat din greșeală pe din afara grajdului și calul, rămas în interior a schimbat parola de acces. Din fericire ai cel mai deștept cal din lume, capabil să facă calcule complexe și ți-ar putea transmite cu ușurință parola, dar, din păcate încă nu l-ai învățat să comunice eficient.
Încuietoarea funcționează în felul următor: pentru a seta o parolă, trebuie să introduci în sistemul încuietorii, din interiorul grajdului, un șir de elemente. Apoi sistemul calculează frecvența cu care apare fiecare valoare din șir, sortează aceste frecvențe crescător și salvează noul șir astfel obținut. Acest șir reprezintă noua parolă care trebuie folosită pentru a deschide ușa din exterior.
Calul știe șirul pe care l-a introdus în sistem, dar pentru că este supărat că a fost încuiat în grajd, nu vrea să-ți facă viața prea ușoară. Acesta te lasă să îl întrebi de un subșir din șirul inițial. Pentru acel subșir, calul va calcula frecvențele în același mod ca sistemul încuietorii și îți va răspunde bazat pe șirul obținut.
După cum s-a menționat mai sus, încă nu ai apucat să perfecționezi capacitățile de comunicare ale calului, prin urmare singurul mod prin care acesta îți poate transmite informații prin ușa închisă (calul are o mimică grozavă, dacă ai fi putut să-i vezi fața lungă, treaba era mult mai ușoară) este să o lovească cu copita. Mai exact, pentru o întrebare, el poate lovi cu copita în ușă de un număr de ori din mulțimea .
Cerință
Va trebui să implementezi două funcții:
descuie_grajdul
: care primește ca parametri numerele și și pune întrebări calului pentru a afla parola. Pentru a face acest lucru, ți se pune la dispoziție funcțiaintreaba_cal
care va face calculele complexe din capul calului.dreseaza_cal
: care primește șirul de frecvențe obținut pentru o întrebare a ta, numerele și și trebuie să returneze un număr din mulțimea
Interacțiune
Funcția std::vector<int> descuie_grajdul(int N, int K)
implementată de concurent:
- primește ca parametri numerele și
- returnează parola (șirul frecvențelor pentru șirul inițial)
- pune întrebări prin intermediul funcției
intreaba_cal
Funcția int intreaba_cal(std::vector<int> indici)
dată de comisie:
- primește ca parametru șirul de indici care descrie subșirul din șirul inițial pentru care este interogat calul. Indicii din vector trebuie să fie distincți, și cu valorile cuprinse între și .
- calculează frecvențele subșirului ales, le ordonează crescător și le transmite funcției
dreseaza_cal
- returnează răspunsul primit de la funcția
dreseaza_cal
nealterat (atâta timp cât răspunul este din mulțimea valorilor permise)
Funcția int dreseaza_cal(int N, int K, std::vector<int> frecvente_sortate)
implementată de concurent:
- primește șirul de frecvențe obținut pentru o întrebare, numărul și numărul
- returnează o valoare din mulțimea
- această funcție nu ar trebui să păstreze memorie de la un apel la altul și să nu depindă decât de memorie locală
Atenție! Codul concurenților va fi rulat în așa fel încât să împiedice folosirea memoriei globale pentru funcția dreseaza_cal
.
Atenție! Singurele declarații permise în program sunt: directivele #include
, #define
(doar pentru constante numerice), using
și declarații de funcții. Nu se pot declara variabile globale, statice sau să se returneze pointeri.
Atenție! Trebuie să includeți fișierul calcule.h
.
Atenție! Fie numărul de indici cu care este apelată funcția intreaba_cal
la a -a interogare, iar egal cu suma . Toate soluțiile cu vor fi considerate incorecte.
Restricții
Fie numărul maxim de interogări făcute în cadrul unei grupe și punctajul maxim al acelei grupe. Atunci, punctajul obținut pe această grupa va fi
In tabelul de mai jos se pot vedea grupele, cu tot cu punctajele maxime ale acestora si limitele .
Grupa | Punctaj | |||
---|---|---|---|---|
1 | 5 | 100 | 2 | 5000 |
2 | 15 | 1000 | 2 | 5312 |
3 | 8 | 1000 | 3 | 3588 |
4 | 8 | 1000 | 5 | 2673 |
5 | 8 | 1000 | 7 | 1974 |
6 | 8 | 1000 | 15 | 1886 |
7 | 8 | 1000 | 30 | 1548 |
8 | 10 | 1000 | 40 | 1198 |
9 | 10 | 1000 | 250 | 1001 |
10 | 20 | 1000 | 1000 | 999 |
Exemplu
Comisie | Concurent | Cal |
---|---|---|
descuie_grajdul(5,2) Șir = 2, 2, 1, 1, 1 |
||
intreaba_cal({0..4}) |
||
dreseaza_cal({2, 3}, 2) → 1 |
||
intreaba_cal({0..3}) |
||
dreseaza_cal({2, 2}, 2) → 0 |
||
intreaba_cal({1..4}) |
||
dreseaza_cal({1, 4}, 2) → 0 |
||
→ {2, 3} |
Explicație
În exemplul de mai sus este exemplificată interacțiunea. Ne imaginăm că codul secret este egal cu . Comisia transmite concurentului că șirul are 5 elemente, și că . Apoi, concurentul poate întreba calul despre mai multe subșiruri - în speță, concurentul în cazul acesta întreabă despre subșirurile cu indicii , apoi , apoi respectiv . În aceste subșiruri, șirul de frecvențe calculat este , apoi , apoi . Funcția dreseaza_cal
descrie informația transmisă de cal concurentului - în cazul acesta el transmite 1, apoi 0, apoi 0 din nou. Concurentul apoi își dă seama că șirul total de frecvențe este , pe care îl și returnează.