www.agora.ro

Ohrid, Macedonia!

BOI 2000

Olimpiada Balcanică de Informatică din anul 2000 s-a desfășurat în orașul Ohrid din Macedonia. Au participat concurenți din Albania, Bulgaria, Cipru, Georgia, Grecia, Iugoslavia, Macedonia, România și Statele Unite ale Americii. În continuare vă prezentăm enunțurile problemelor din cele două zile ale competiției.

P070007: Piața

Pescarul Clement a prins N pești și i-a adus la piața de pește. Angajații de la piața de pește împachetează peștii în pachete cu diferite greutăți. Fiecare pachet poate avea unul sau mai mulți pești.

Să presupunem că sunteți primul client și puteți alege greutatea pachetului dumneavoastră. Câte greutăți diferite putem obține pentru pachete?

Limite

  • NŁ500 este un număr întreg pozitiv care indică numărul peștilor.
  • tiŁ1000 este un număr întreg pozitiv care reprezintă greutatea celui de-al i-lea pește.

Timp de execuție: 75 de secunde

Fișier de intrare: MARKET.IN

Pe prima linie a fișierului de intrare se află numărul întreg pozitiv N. Pe fiecare dintre următoarele N linii se află un număr întreg pozitiv ti.

Fișier de ieșire: MARKET.OUT

Ieșirea constă într-un număr pozitiv întreg K care reprezintă numărul greutăților distincte care pot fi obținute.

Exemplu

MARKET.IN MARKET.OUT

5 27

800

200

354

18

182

P070008: Dimensiune fractală

Clement a învățat la școală cum să calculeze dimensiunea fractală a unei figuri geometrice. În acest scop el desenează o grilă unitate având coordonate întregi. Apoi desenează pe grilă o figură geometrică având N vârfuri. Aceste N vârfuri definesc un poligon care nu este neapărat convex și ale cărui laturi nu se intersectează. El trebuie să numere cele K1 pătrate unitate de pe grilă care intersectează figura. Prin intersecție înțelegem faptul că pătratul are cel puțin un punct comun cu interiorul figurii. După aceea șterge liniile grilei care au coordonate impare și numără cele K2 pătrate ale noii grile care intersectează figura. Dimensiunea fractală este calculată folosind o anumită formulă care depinde de K1 și K2. Clement dorește să calculeze dimensiunea fractală a Lacului Ohrid. Determinați K1 și K2.

Limite

  • 2<N<1000 este un număr întreg pozitiv care reprezintă numărul vârfurilor.
  • Fiecare vârf este definit prin două numere întregi xi și yi reprezentând coordonatele XY ale vârfului(-32000Łxi, yiŁ32000).
  • fiecare vârf este legat de vârful precedent printr-o linie dreaptă; primul vârf este și el legat de ultimul vârf.

Timp de execuție: 1 secundă

Fișier de intrare: FRACTAL.IN

Prima linie a fișierului de intrare conține numărul întreg N. Fiecare dintre următoarele N linii conține două numere întregi xi și yi.

Fișier de ieșire: FRACTAL.OUT

Ieșirea constă într-o singură linie care conține numerele K1 and K2.

Exemplu

FRACTAL.IN FRACTAL.OUT

4 110 30

0 0

10 0

20 10

10 10

P070009: Scufundări

În fiecare an în Ohrid se desfășoară cursuri de scufundări. În cadrul acestor cursuri se desfășoară diferite activități. Una dintre ele este scufundarea într-o parte a unei stânci, trecerea printr-un pasaj subacvatic și ieșirea de cealaltă parte a stâncii. Întregul grup de N studenți dispune de un singur tub de oxigen. Maximum două persoane pot folosi tubul de oxigen în același timp. Fiecare scufundător are o viteză proprie și atunci când doi studenți se scufundă împreună, ei se vor deplasa cu viteza celui mai lent dintre ei. Există M perechi de studenți care nu se plac unul pe altul și care nu se pot scufunda în același timp.

Stabiliți un program pentru a muta cât mai repede grupul de studenți dintr-o parte a stâncii în cealaltă parte.

Limite

  • NŁ6000 este un număr întreg pozitiv care reprezintă numărul studenților din grup. Studenții sunt etichetați cu numerele 1, 2, ..., N.
  • MŁ6000 este un număr întreg pozitiv care reprezintă numărul perechilor de studenți care nu se pot scufunda împreună.
  • ti este un număr întreg pozitiv care reprezintă timpul necesar celui de-al i-lea pentru a trece dintr-o parte în alta a stâncii.
  • Tubul de oxigen poate fi mutat dintr-o parte în alta a stâncii pe sub apă. Tubul de oxigen are capacitatea nelimitată. Există întotdeauna cel puțin o soluție.

Timp de execuție: 1 secundă

Fișier de intrare: DIVING.IN

Prima linie a fișierului de intrare conține două numere întregi N și M. Fiecare dintre următoarele N linii conține un număr întreg ti. Fiecare dintre următoarele M linii conține două numere întregi reprezentând o pereche de studenți care nu se pot scufunda împreună.

Fișier de ieșire: DIVING.OUT

Prima linie a fișierului de ieșire va conține un număr întreg reprezentând timpul minim necesar pentru traversarea tuturor studenților. Următoarele linii descriu un program de traversare în timp minim. Fiecare linie reprezintă o traversare și constă din unul sau două numere întregi reprezentând studentul (studenții) care participă la traversarea respectivă.

Exemplu

DIVING.IN DIVING.OUT

4 2 6

1 3 1

2 1

1 4 2

2 3

3 4 3 1

2 3

P070010: Poduri

Naum s-a întors în satul său Elshani cu o grămadă de bani. În fiecare zi locuitorii din Elshani se duc la muncă în unul dintre satele vecine Peshtani și Lagadin. Există o mulțime de drumuri prin munți până la destinația lor. Pentru a-ți ajuta vecinii să-și călătoriile Naum dorește să construiască un pod care poate avea lungimea maximă Lmax.

Găsiți locul în care poate fi construit un pod care satisface următoarele criterii:

  • Va exista un drum nou de la Elshani la Peshtani mai scurt decât cel mai scurt drum existent
  • Va exista un drum nou de la Elshani la Lagadin mai scurt decât cel mai scurt drum existent
  • Suma lungimilor noilor drumuri minime va fi minimă.

Limite

  • 3ŁNŁ2000 este un număr întreg pozitiv reprezentând numărul de puncte.
  • Punctele sunt etichetate cu 1,2,...,N, unde 1 reprezintă punctul de pornire (satul Elshani), 2 este una dintre destinații (satul Peshtani) și 3 este cealaltă destinație (satul Lagadin). Două puncte pot fi conectate printr-un singur punct. Lungimea unui drum este cea mai scurtă distanță dintre punctele corespunzătoare. Din fiecare punct pleacă cel mult 20 de drumuri.
  • -32000Łxi,yiŁ32000 sunt numere întregi reprezentând coordonatele XY ale celui de-a i-lea punct.
  • MŁ5000 este un număr întreg pozitiv reprezentând numărul drumurilor dintre puncte.
  • Lmax este un număr real pozitiv reprezentând lungimea maximă a podului.
  • Erorile de rotunjire nu vor afecta rezultatul obținut.
  • Dacă există o soluție atunci aceasta este unică.

Timp de execuție: 15 secunde

Fișier de intrare: BRIDGE.IN

Prima linie a fișierului de intrare conține două numere întregi N și M și un număr real Lmax. Fiecare dintre următoarele N linii conține două numere xi și yi. Fiecare dintre următoarele M linii conține două numere întrgi reprezentând punctele legate de un drum.

Fișier de ieșire: BRIDGE.OUT

Dacă există o soluție, ieșirea constă în două numere întregi K1 și K2 reprezentând punctele între care va fi construit podul. Dacă podul nu poate fi construit în condițiile date, se va scrie 0 0 pe prima linie, iar pe a doua linie se vor scrie două numere reale d1 și d2 cu o precizie de 0 (zero) zecimale. d1 este drumul minim între punctele 1 și 2, iar d2 este drumul minim între punctele 1 și 3.

P070011: Păianjen

Un păianjen și un țânțar se află într-o cutie de sticlă de dimensiuni L, M și N. Ei se deplasează pe suprafețele cutiei. Ei nu pot zbura și nu cad, indiferent de suprafața pe care se află. Găsiți o strategie pentru ca păianjenul să prindă țânțarul cât mai repede.

Programul dumneavoastră va trebui să joace împotriva unor module controlate de calculator. Cei doi jucători mută alternativ. Programul dumneavoastră va controla mișcările păianjenului, iar modulul controlat de calculator pe cele ale țânțarului.

Limite

  • L,M,NŁ10000 sunt numere întregi reprezentând dimensiunile cutiei.
  • Cutia se află într-un sistem de coordonate XYZ cu un colț în origine și celelalte colțuri pe axe.
  • Păianjenul și țânțarul se pot afla numai în puncte de coordonate întregi pe suprafața cutiei, după cum se arată în figura 1.

Figura 1: Suprafețele cutiei

  • La o mutare păianjenul poate sări așa cum se arată în figura 2.

Figura 2: Mutările păianjenului

  • La o mutare țânțarul poate sări așa cum se arată în figura 3.

Figura 3: Mutările țânțarului

  • Atât păianjenul cât și țânțarul se pot muta de pe o suprafață pe alta trecând peste o muchie.
  • Păianjenul prinde țănțarul dacă reușește să ajungă în aceeași poziție cu acesta.

Timp de execuție: 4 secunde

Fișier de intrare: SPIDER.IN

Prima linie a intrării constă din trei numere întregi L, M și N. Cea de-a doua linie constă din trei numere întregi xs, ys, zs reprezentând poziția inițială a păianjenului. Ultima linie constă din trei numere întregi xb, yb, zb reprezentând poziția inițială a țânțarului.

Fișier de ieșire: SPIDER.OUT

Apelul subprogramului Finish produce un fișier de ieșire. Acest fișier nu poate fi modificat de programul dumneavoastră. Fișierul va conține numărul de mutări, indicația că programul a funcționat corect sau motivul pentru care acesta nu a funcționat corect.

Evaluare

Un test nu este punctat dacă apar:

  • Două apeluri consecutive pentru movespider.
  • Două apeluri consecutive pentru movebug.
  • Mutări nepermise ale păianjenului.

Fie T numărul minim de mutări ale păianjenului necesare pentru a prinde țânțarul și S numărul de mutări ale păianjenului efectuate de programul dumneavoastră.

Dacă S<T+3 atunci testul va fi punctat cu 10 puncte. Dacă T+3ŁS<1.2*T atunci testul va fi punctat cu 8 puncte. Dacă 1.2*TŁS<1.4*T atunci testul va fi punctat cu 5 puncte.

Instrucțiuni pentru programatorii în Pascal

Veți avea un unit numit USpider.tpu. Sursa dumneavoastră va trebui să conțină la început instrucțiunea:

uses USpider;

Unit-ul conține 4 proceduri: init, movespider, movebug and finish.

procedure Init;

Procedura Init ar trebui apelată la începutul programului.

procedure movespider(xns,yns,zns:Integer);

Procedura movespider este folosită pentru a indica noile coordonate ale păianjenului după o mutare.

procedure movebug(var xnb,ynb,znb:Integer);

Procedura movebug implementează strategia calculatorului și returnează noile coordonate ale țânțarului după o mutare.

procedure Finish;

Procedura Finish trebuie apelată după ce păianjenul a prins țânțarul. Această procedură va întrerupe și execuția programului.

La început programul dumneavoastră va trebui să apeleze procedura Init. Apoi programul va trebui să apeleze alternativ procedurile movespider și movebug. După apelul unei proceduri movespider, care mută păianjenul în poziția țânțarului, va trebui apelată procedura Finish.

Instrucțiuni pentru programatorii în C/C++

Veți avea un fișier obiect numit USpider.obj și un fișier header numit USpider.h.

Înaintea rezolvării problemei va trebui să deschideți un nou proiect cu numele Spider.prj și care va conține două fișiere: USpider.obj și fișierul care conține codul sursă. La începutul fișierului sursă va trebui să folosiți instrucțiunea: #include "USpider.h" sau instrucțiunea #include <USpider.h>.

Fișierul Spider.obj conține 4 funcții: Init(), movespider(), movebug() și Finish().

void Init();

Funcția Init() trebuie apelată la începutul programului.

void movespider(int xns,int yns,int zns);

Funcția movespider() este folosită pentru a indica noile coordonate ale păianjenului după o mutare.

void movebug(int *xnb,int *ynb,int *znb);

Funcția movebug() implementează strategia calculatorului și returnează noile coordonate ale țânțarului după o mutare.

void Finish();

Funcția Finish() trebuie apelată după ce păianjenul prinde țânțarul. Această funcție întrerupe și execuția programului.

La început programul dumneavoastră va trebui să apeleze funcția Init(). Apoi programul va trebui să apeleze alternativ funcțiile movespider() și movebug(). După apelul unei proceduri movespider(), care mută păianjenul în poziția țânțarului, trebuie apelată funcția Finish().

Exemplu

SPIDER.IN

10 12 8

10 11 1

5 12 2

Interfața cu unitul Coord. returnate

Init;

movespider(9,12,2);

movebug(xb, yb, zb) ; (4, 12, 1)

movespider(7,12,1);

movebug(xb, yb, zb); (3, 12, 0)

movespider(5,12,0);

movebug(xb, yb, zb); (2, 11, 0)

movespider(3,11,0);

movebug(xb, yb, zb); (1, 10, 0)

movespider(1,10,0);

Finish;

Pentru acest exemplu numărul minim de mutări este 5.

P070012: Pești

Pescarul Naum a prins N pești. Greutatea fiecărui pește ti este măsurată pe țărm. Naum lucrează pentru o companie de pește și are dreptul să ia acasă cel mult T grame de pește. El vrea să ia acasă un număr minim de pești, dar care au o greutate totală maximă L(ŁT).

Decideți care pești vor fi luați.

Limite

  • NŁ500000 este un număr întreg pozitiv care reprezintă numărul de pești.
  • TŁ7000 este un număr întreg pozitv care reprezintă greutatea maximă totală a peștilor care pot fi duși acasă.
  • tiŁ35000 este un număr întreg pozitiv care reprezintă greutatea celui de-al i-lea pește.

Timp de execuție: 4 secunde

Fișier de intrare: FISH.IN

Prima linie a fișierului de intrare conține două numere întregi N și T. Fiecare dintre următoarele N linii conține un număr întreg ti representând greutatea celui de-al i-lea pește.

Fișier de ieșire: FISH.OUT

Dacă nu există o soluție pentru T grame, ieșirea va conține o soluție pentru cel mai mare număr întreg LŁT. prima linie a ieșirii constă într-un număr întreg K reprezentând numărul peștilor care trebuie duși acasă. Fiecare dintre următoarele K linii va conține un număr întreg ki reprezentând greutatea celui de-al i-lea pește care trebuie dus acasă.

Exemplu

FISH.IN FISH.OUT

10 280 2

300 200

10 80

30

80

200

20

20

60

10

100

[cuprins]