enemies

Time limit: 0.3s Memory limit: 512MB Input: Output:

Una dintre cele mai neînțelese relații dintre oameni este cea de dușmănie. La prima vedere pare a nu fi nicio regulă sau structură legată de aceste relații, doar legende și povești. De exemplu, faimoasa expresie “Dușmanul dușmanului meu este prietenul meu“ pare a fi doar o legendă și nimic mai mult.

O echipă de cercetători din Dorohoi crede că a reușit să inventeze un dispozitiv cu ajutorul căruia să poată studia aceste relații de dușmanie. Ei au la dispoziție NN cobai voluntari numerotați de la 00 la N1N - 1. Aceștia au MM relații de dușmănie XiYiX_i - Y_i (XiYi,0iM1X_i \neq Y_i , 0 \leq i \leq M - 1) cu semnificația că persoana XiX_i (0XiN1)0 \leq X_i \leq N - 1) se află într-o relație de dușmănie cu persoana YiY_i (0YiN10 \leq Y_i \leq N - 1).

Dispozitivul este format dintr-o cameră în care pot intra o parte din acești NN oameni. Apoi acesta poate fi activat și după numeroase calcule, extrapolări și integrări va afișa pe un ecran numărul de relații de dușmănie între oamenii din cameră și cei aflați în exterior.

Cercetătorii trebuie să deducă toate relațiile de dușmănie fără să utilizeze dispozitivul de prea multe ori, altfel riscă ca unul din voluntari să îi considere dușmani și din aceasta cauză să nu mai poată să deducă relațiile. Voi trebuie să le spuneți cum să utilizeze dispozitivul de fiecare dată și la final să deduceți relațiile de dușmănie ale celor NN voluntari.

Detalii de implementare

Trebuie să implementați următoarea funcție:

std::vector<std::pair<int, int>> find_enemies(int N);

Funcția find_enemies va fi apelată exact o dată pentru fiecare test. NN va reprezenta numărul de oameni pentru care se caută relațiile de dușmănie. Funcția trebuie să întoarcă un vector de perechi reprezentând toate relațiile de dușmănie dintre cei NN oameni. Se acceptă orice soluție corectă astfel că cei doi indici din cadrul unei perechi, cât și perechile pot fi în orice ordine. Indicii oamenilor trebuie să fie valori întregi de la 00 la N1N - 1. Puteți apela următoarea funcție în scopul găsirii acestor relații:

int split_people(std::string split);

Atenție! Această funcție nu trebuie implementată de către voi. Graderul va implementa această funcție. Argumentul splitsplit trebuie să fie format din exact NN caractere care sunt fie 00, fie 11, în caz contrar graderul va termina programul din execuție și va nota testul ca fiind incorect. Funcția va întoarce câte relații de dușmănie sunt între oamenii din cameră și cei din exteriorul acesteia, oamenii fiind repartizați în funcție de caracterul corespunzător. Dacă spliti=0split_i = 0 atunci al ii-lea om va rămâne în afara camerei, iar dacă este 11 al ii-lea om va intra în camera dispozitivului.

Puteți apela această funcție de maxim 20 00020 \ 000 de ori, iar scorul vostru va fi calculat în funcție de acest număr (vezi secțiunea Punctare).

Punctare

Pentru orice test punctajul maxim se obține dacă funcția split_people este apelată de cel mult 10 00010 \ 000 de ori. Dacă numărul de apeluri ale acestei funcții în cadrul unui test este mai mare decât 10 00010 \ 000, dar mai mic sau egal cu 20 00020 \ 000 atunci punctajul obținut pe acel test este 75%75\% din punctajul asociat testului.

# Punctaj Restricții
1 16 1N1000M8001 \leq N \leq 100 \newline 0 \leq M \leq 800
2 8 1N8000M8001 \leq N \leq 800 \newline 0 \leq M \leq 800 \newline Cei NN oameni pot fi partiționați în 22 mulțimi AA și BB astfel încât orice om din mulțimea AA este în relație de dușmănie cu orice om din mulțimea BB. Expresia “Dușmanul dușmanului meu este prietenul meu“ este cât se poate de adevărată
3 40 1N8001 \leq N \leq 800 \newline Graful obținut din relațiile de dușmănie reprezintă un lanț.
4 20 1N8001 \leq N \leq 800 \newline Graful obținut din relațiile de dușmănie reprezintă un arbore.
5 16 1N8000M8001 \leq N \leq 800 \newline 0 \leq M \leq 800

Punctajul pentru un subtask este minimul punctajelor obținute pe testele din acel subtask.

Atenție! Graderul oficial NU este adversarial. Asta înseamnă că relațiile de dușmănie sunt decise la începutul rulării graderului și nu depind de diferitele apeluri ale funcției split_people.

Model de grader

Atenție! Acest grader nu este neapărat cel folosit pentru evaluarea submisiilor.

Vi se pune la dispoziție un grader pentru a vă putea compila și testa codul local. Acesta va citi de la consolă datele de intrare în următorul format:

  • linia 11: N MN \ M, reprezentând numărul de oameni, respectiv numărul de relații de dușmănie.
  • linia 2+i2 + i (0iM10 \leq i \leq M - 1): Xi YiX_i \ Y_i, reprezentând perechi de oameni aflați în relație de dușmănie.

Dacă programul vostru întoarce corect relațiile de dușmănie folosind maxim 20 00020 \ 000 de apeluri ale funcției split_people atunci graderul va afișa Accepted: q, unde qq reprezintă numărul de apeluri ale funcției split_people.

Altfel, graderul va afișa în consolă Wrong Answer: MSG, unde MSGMSG poate avea una din următoarele valori și semnificații:

  • invalid split: O valoare a lui splitsplit dată ca parametru funcției split_people este invalidă. Mai exact, fie lungimea lui split nu este egală cu NN, fie unul din caracterele din split nu este 00 sau 11.
  • too many splits: Funcția split_people a fost apelată de mai mult de 20 00020 \ 000 de ori.
  • answer size mismatch: Funcția find_enemies a întors un număr diferit de relații de dușmănie decât numărul corect.
  • wrong guess: Funcția find_enemies a întors alte relații de dușmănie decât cele corecte.

De asemenea, graderul va scrie în fișierul enemies.txt toate relațiile de dușmănie întoarse de funcția find_enemies. Pe primul rând va afișa numărul de relații întoarse, apoi fiecare relație pe câte un rând, indicii oamenilor dintr-o relație fiind separați prin exact un spațiu.

Graderul și testele nu sunt cele din timpul concursului!

Exemplu

Să presupunem că N=4N = 4, M=3M = 3 și relațiile de dușmănie sunt 010 - 1, 020 - 2 și 131 - 3. O succesiune de apeluri ale funcției split_people care determină aceste relații este următoarea:

Apel Valoare întoarsă
split_people([0]) 2
split_people([0, 1]) 2
split_people([0, 2]) 1
split_people([0, 3]) 3
split_people([0, 1, 2]) 1
split_people([0, 1, 3]) 1
split_people([0, 2, 3]) 2

Explicație

Pentru primul apel al funcției split_people, 00 are exact 22 relații de dușmănie, deci funcția va întoarce 22.
Pentru cel de-al 44-lea apel al funcției split_people toate cele 33 relații de dușmănie sunt între un om din cameră și unul din afara acesteia.
Pentru cel de-al 66-lea apel al funcției split_people numai relația de dușmănie 020 - 2 va fi contorizată de dispozitiv.
În final, funcția find_enemies trebuie să întoarcă [(3,1),(0,2),(0,1)][(3, 1), (0, 2), (0, 1)].

Log in or sign up to be able to send submissions!