registers

Time limit: 0.03s
Memory limit: 64MB
Input:
Output:

Tocmai ți-ai cumpărat un nou calculator de la niște surse foarte obscure pe care vrei să joci „Minează-Meșteșugește”. Din păcate, calculatorul nu este ce ți-ai imaginat și nici măcar nu respectă specificațiile pe care le-ai găsit pe internet. Totuși, dorești să vezi dacă poți găsi o utilitate cu ce ți-ai cumpărat sau măcar să înveți cum funcționează.

Calculatorul tău conține 12 regiștrii și un set de patru instrucțiuni.

Înainte să te poți ocupa de proiecte mărețe, vrei să începi cu ceva mai ușor, și anume să calculezi produsul a două numere, folosind limbajul de asamblare care va fi descris mai jos.

Limbajul de asamblare

  • Pe prima linie a programului se va afla instrucțiunea de declarare a regiștrilor. Aceasta este de forma: registers <register1> <register2> . . . <registerN>
    Această instrucțiune declară regiștrii ce vor fi utilizați ulterior în program. Aceștia vor fi inițializați cu valoarea 0. Numele regiștrilor X, Y și Out sunt rezervați de sistem și nu au voie să apară în intermediul acestei instrucțiuni. Această instrucțiune nu are voie să apară decât o singură dată la începutul programului. Numele regiștrilor pot fi orice șir de caractere care nu conțin spații albe sau caracterul sfârșit de linie (newline). Programul va avea voie să folosească doar regiștrii declarați sau cei trei rezervați de sistem.
    Atenție! Literele mari și literele mici sunt distincte, astfel regiștrii cu numele a și A sunt doi regiștrii diferiți.
    Regiștrii X și Y vor fi inițializați cu numerele de înmulțit, iar registrul Out va fi inițializat cu 0.
  • Un label (etichetă) are forma label: și reprezintă un loc în program situat printre instrucțiuni ce reprezintă o zonă de cod de la care se continuă firul execuției în cazul unei instrucțiuni jeq, instrucțiune ce va fi explicată ulterior. Numele label-urilor trebuie să respecte aceleași reguli ca numele regiștrilor.
  • Există trei tipuri de instrucțiuni:
  1. inc <register> – această instrucțiune crește valoarea stocată în registrul dat ca parametru cu o unitate;
  2. dec <register> – această instrucțiune scade valoarea stocată în registrul dat ca parametru cu o unitate; în cazul în care valoarea registrului este 0, instrucțiunea nu are niciun efect;
  3. jeq <register1> <register2> <label> – această instrucțiune compară valorile stocate de cei doi regiștrii dați ca parametru; în caz de egalitate, firul de execuție continuă de la prima instrucțiune de după label-ul dat ca parametru, altfel firul de execuție continuă de unde a rămas.
    Instrucțiunile sunt executate una câte una, în ordinea în care apar în fișier, sau, în cazul instrucțiunii jeq, de la prima instrucțiune de după label-ul dat ca parametru în caz de egalitate.
  • O linie ce începe cu caracterul # este tratată ca și un comentariu și va fi ignorată.

Din nefericire, când ai despachetat calculatorul, l-ai scăpat pe jos. Din această cauză, instrucțiunile inc și dec nu funcționează cum trebuie. Astfel, când aceste instrucțiuni sunt executate, există șanse de 50% ca registrul dat să nu fie incrementat, respectiv decrementat, iar acesta rămâne neschimbat, iar execuția continuă cu următoarea instrucțiune.

Execuția se termină după ce ultima linie este executată și nu mai există o instrucțiune ce ar urma în firul de execuție.

Fiecare linie care nu este goală are voie să conțină doar un comentariu, o instrucțiune sau un label, dar nu mai multe la un loc. Spațiile puse în plus sau liniile goale puse în scopul indentării sunt ignorate.

Restricţii

  • 0 ≤ X, Y ≤ 1 000
  • Programul are voie să declare maxim 12 regiștrii
  • Fie T numărul de instrucțiuni inc, dec și jeq executate cu succes (incluzând și operațiile de dec care nu au efect). T poate fi cel mult 100 000 000
  • Programul are voie să modifice regiștrii X și Y, dar produsul care trebuie calculat trebuie să fie cel dintre valorile inițiale ale celor doi regiștrii
  • Concurentul nu va citi nimic din stdin și va afișa în stdout programul
  • Notă: Puteți selecta "Output Only" ca limbaj pentru a trimite doar programul sau puteți declara un șir de caractere în C++ pe mai multe rânduri astfel:
std::string longString = R""""( 
line1
line2
)"""";

Subtask 1 (10 puncte)

  • Y = 1

Subtask 2 (20 puncte)

  • Y = 2

Subtask 3 (15 puncte)

  • Y ≤ 30

Subtask 4 (55 puncte)

  • X, Y ≥ 30. Vezi modul de punctare

Punctare

Punctajul obținut pe ultimul subtask va fi de la 15 la 55 de puncte, în funcție de numărul de instrucțiuni executate cu succes (numărul T definit în restricții).

Orice soluție ce are T ce are mai puțin de 13.5(XY + X + Y + 1) obține 55 de puncte.

Altfel, fie factor definit ca fiind factor=TXY+X+Y+1factor = \frac{T}{XY + X + Y + 1}. Astfel, punctajul obținut va fi max(15.055.0,e(factor13.51)0.75)max(\frac{15.0}{55.0}, e^{−(\frac{factor}{13.5}-1)^{0.75}}).

Exemplu

stdout

registers a b
# Acesta este un comentariu
inc a
inc b
jeq a b label1
inc a
label1:
inc b

Explicații

Notă: Acest program din exemplu nu rezolvă nimic. Acesta este dat doar pentru a vă familiariza cu sintaxa și modul de funcționare. De asemenea, vom presupune că instrucțiunile de inc a și prima instrucțiune inc b sunt mereu executate, iar a doua instrucțiune inc b nu se execută. În realitate, aceeași instrucțiune poate sau nu să fie executată.

Testul folosit va fi X = 15 și Y = 20.

Prima instrucțiune declară regiștrii a și b.

Următoarea instrucțiune executată va fi cea de pe rândul 4 (inc a). Valoarea lui a va deveni 1.

Următoarea instrucțiune executată va fi cea de pe rândul 5 (inc b). Valoarea lui b va deveni 1.

Următoarea instrucțiune executată va fi cea de pe rândul 6 (jeq a b label1). Cum valorile lui a și b sunt egale, firul execuției va continua cu instrucțiunea de pe rândul 9.

Instrucțiunea de pe rândul 9 nu va fi executată. În acest punct, cum nu mai urmează nicio instrucțiune, programul a terminat.

În final, valoarea registrului Out este 0. Acest răspuns este în mod evident greșit, deoarece nu calculează produsul lui X și Y. Pentru a primi puncte pe acest test, răspunsul din Out trebuie să fie 15 · 20 = 300.

Numărul de instrucțiuni executate cu succes este 3.

Problem info

ID: 233

Editor: liviu

Source: Lot 2022 Baraj 2 Seniori: Problema 2

Tags:

Lot 2022 Baraj 2 Seniori

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