www.agora.ro

Încercați-vă puterile!

 

PROBLEME propuse pentru REZOLVARE

În toamna anului trecut a avut loc etapa regională a concursului studențesc ACM, la care au participat 35 echipe din mai multe țări. Concursul a fost câștigat de prima echipă a Universității București, urmată de prima echipă a Universității Politehnice din București. Aceste două echipe vor participa la etapa finală a concursului ACM, organizată anul acesta la Eindhoven (Olanda).

P029901: Țara Confuziei

În călătoria sa în jurul lumii un turist a ajuns în Țara Confuziei. În această țară există mai multe intersecții unite prin străzi cu sens unic. La fiecare intersecție pot exista mai multe străzi marcate cu "Nord", "Est", "Sud" sau "Vest". Când turistul ajunge la o intersecție el alege una dintre străzile marcate în planul său de călătorie și se îndreaptă spre intersecția la care duce această stradă. Deoarece semnele sunt ambigue sau nepotrivite pot apărea câteva situații ciudate:

- Nu sunt marcate decât străzile care pornesc dintr-o intersecție, nu și cele care sosesc în intersecție. Turistul poate pleca dintr-o intersecție numai pe o stradă marcată (cu sens unic).

- Pentru fiecare semn (N,E,V,S) pot exista mai multe străzi care pleacă în acea direcție, dar se poate întâmpla să nu existe nici una.

- Dacă turistul vine din intersecția A și ajunge în intersecția B printr-o stradă marcată cu "Nord" în intersecția A, nu înseamnă neapărat că el poate ajunge înapoi din B în A alegând o stradă marcată cu "Sud"; poate exista o stradă de la B la A marcată cu un alt semn sau s-ar putea să nu existe nici o stradă de la B la A.

- O stradă marcată, de la intersecția A poate duce la aceeași intersecție.

De exemplu, tabelul 1 definește o hartă a străzilor în Țara Confuziei.

În acest exemplu călătorul aflat în intersecția 1 poate alege una dintre străzile spre Nord pentru a ajunge fie în intersecția 2, fie în intersecția 3, sau să meargă spre Sud și să ajungă tot în intersecția 1. Turistul nu are alte opțiuni atunci când se află în intersecția 1. Din intersecția 5 el poate merge fie spre Nord, și ajunge astfel în intersecția 6, fie spre Sud, și ajunge în intersecția 1.

Turistul are mai multe planuri de călătorie. Fiecare plan este o secvență formată din literele ‘N', ‘E', ‘S' și ‘V' care indică direcția pe care turistul ar trebui să o aleagă în intersecția în care se află. Un plan este considerat corect dacă există un drum de lungime egală cu lungimea secvenței între intersecția de pornire și intersecția de sosire, drum care trebuie să respecte direcțiile precizate în plan. În caz contrar planul este incorect. Observați că pentru același plan pot exista nici unul, unul sau mai multe astfel de drumuri.

Pentru exemplul dat, dacă turistul pornește din intersecția 1 și dorește să ajungă în intersecția 6, atunci secvența ‘SSSNEEVN' este corectă deoarece există drumul: 1 (plecare), 1, 1, 1, 3, 2, 4, 5, 6 (sosire) de lungime 8 care duce la sosire. Secvența ‘NEVNS' este, în acest caz, incorectă: turistul poate alege drumul: 1 (plecare), 2, 4, 5, 6 și apoi nu poate merge spre Sud. Observați că acest drum nu este corect, deoarece nu are aceeași lungime ca și secvența. Turistul mai poate alege drumul: 1 (plecare), 3, 2, 3, 5, 1, (ultima intersecție nu este sosirea dorită) sau drumul: 1 (start), 3, 4, 5, 6 (lungimea drumului nu este aceeași cu lungimea secvenței).

Dându-se o hartă a străzilor, scrieți un program care va afla care dintre planurile date sunt corecte și care nu, precum și intersecția de plecare și cea de sosire.

Fișierul de intrare conține mai multe seturi de date. Fiecare set de date reprezintă o hartă de străzi, intersecția de plecare și cea de sosire, precum și câteva planuri date. Există exact o linie vidă între două seturi de date consecutive.

Fiecare set de date începe cu o linie care conține un întreg care reprezintă numărul de intersecții. Numărul 0 marchează sfârșitul fișierului de intrare. Intersecțiile sunt numerotate pornind de la 1. Pe linia următoare se află doi întregi separați prin spații care indică intersecția de plecare și cea de sosire. Următoarele linii sunt grupate câte patru pentru fiecare intersecție. Aceste patru linii indică intersecțiile adiacente (separate prin spații) în care se poate ajunge direct din intersecția dată prin străzile marcate cu Nord (prima linie), Est (a doua linie), Sud (a treia linie) și Vest (a patra linie). Dacă o linie conține un singur 0 înseamnă că nu există străzi marcate cu semnul respectiv în intersecția dată. Urmează o linie care conține un singur întreg NP care indică numărul planurilor date. Următoarele NP linii conțin secvențele (o secvență pe linie). Planul constă din literele ‘N', ‘E', ‘S' sau ‘V'. Numărul maxim de intersecții este de 30, și lungimea maximă a planului este 80.

Pentru fiecare set de date, programul trebuie să afișeze o linie care să conțină propoziția ‘Fuzzyland #:' și câte o linie pentru fiecare plan care să cuprindă răspunsul ‘DA' dacă secvența este corectă sau ‘NU' în caz contrar.

Exemplu:

Intrare: A.DAT

6 5 0 5 6

1 6 6 6 0

2 3 0 0 7

0 1 0 0

1 0 3 2

0 0 0 0

0 0 5 0

4 0 2 0

0 0 0 0

3 3 0 0

5 SSSNEEVN 4 5 3

2 4 NEVNS 6 NEVENSVSSN

0 SNEVSNEVN 0 SSVN

0 0 SNN

0 7 0

0 1 7 0 0

0 2 4

Ieșire: - ecran

Fuzzyland #1:

DA

NU

DA

Fuzzyland #2:

DA

NU

NU

P029902: Numărul majoritar

Numărul majoritar al unui șir nevid de N numere este acel număr care apare de mai mult de N/2 ori în secvență. De aceea, pentru un șir nevid, există cel mult un astfel de număr. De exemplu, șirul 3, 3, 4, 2, 4, 4, 2, 4, 4 are numărul majoritar 4, iar șirul 3, 3, 4, 2, 4, 4, 2, 4 nu are un număr majoritar.

Un fișier text conține șiruri nevide de întregi lungi. Fiecare șir, care poate fi destul de lung, începe cu un număr care indică numărul de întregi lungi din șir. Acest număr nu face parte din șir. Numerele pot fi separate prin caractere albe (spații, tab-uri și caractere de sfârșit de linie). Datele de intrare se consideră corecte.

Scrieți un program care, citește mai multe șiruri de întregi lungi din fișierul de intrare și afișează numărul majoritar al șirului. Dacă nu există un astfel de număr, se va scrie mesajul ‘Nu exista numar majoritar'. Rezultatele se vor afișa la ieșirea standard pe linii separate.

Exemplu:

Intrare: B.DAT

6

100000 –2 56 100000 –2 56

5

-2 100 –2 –2 1001

1

1000

Ieșire - ecran

Nu exista numar majoritar

-2

1000

P029903: Rețele sigure

Un server S al unei rețele de calculatoare este considerat critic dacă există cel puțin alte două servere A și B astfel încât A, B și S sunt diferite și toate drumurile din rețea care conectează A și B trec prin S (o cădere a lui S deconectează A și B). Un exemplu este arătat în figură, unde serverele critice sunt 1 și 3. Vom spune că o rețea este sigură dacă nu conține servere critice. Se știe că:

(1) legăturile dintre servere sunt bidirecționale;

(2) un server nu poate fi conectat direct cu el însuși;

(3) rețeaua poate avea sub-rețele autonome.

Scrieți un program care găsește sub-rețelele sigure maximale dintr-o rețea dată. O sub-rețea este maximală dacă nu poate fi unită cu o altă sub-rețea sigură, astfel încât să rezulte o rețea sigură mai mare. Programul trebuie să citească seturi de date dintr-un fișier text. Fiecare set specifică structura unei rețele și are următorul format:

nr_servere

server0(nr_conexiuni_directe)server_conectat...

server_conectat

...

servernr_servere-1 (nr_conexiuni_directe)

server_conectat ... server_conectat

Prima linie conține un întreg nr_servereł0 care indică numărul de servere din rețea. Următoarele nr_servere linii (câte una pentru fiecare server din rețea), sunt ordonate în mod aleator și indică modul în care sunt conectate serverele. Linia corespunzătoare serverului serverk, 0ŁkŁnr_servere-1, specifică numărul conexiunilor directe dintre serverk și serverele care sunt conectate direct cu acesta. Serverele sunt reprezentate prin întregi între 0 și nr_servere-1. Elementele unei linii de date sunt separate prin cel puțin un spațiu. Datele de intrare sunt corecte.

Rezultatul programului trebuie afișat la ieșirea standard. Pentru fiecare rețea din fișierul de intrare programul trebuie să afișeze numărul sub-rețelelor sigure maximale și apoi serverele fiecărei sub-rețele, câte o sub-rețea pe linie. Ieșirea pentru o rețea este urmată de o linie vidă. Serverele unei sub-rețele trebuie afișate în ordine crescătoare și separate printr-un singur spațiu. Sub-rețelele trebuie afișate în ordine crescătoare după prima lor componentă.

Exemplu:

Intrare: C.DAT

8

0 (1) 1

1 (3) 2 0 3

2 (2) 1 3

3 (3) 1 2 4

4 (1) 3

7 (1) 6

6 (1) 7

5 (0)

Ieșire: - ecran

5 sub-rețele

0 1

1 2 3

3 4

5

6 7

P029904: Drumuri pe autostradă

O companie dorește să construiască o autostradă între două orașe. În fazele inițiale ale proiectului compania folosește un satelit digital pentru a determina cele mai bune trasee pentru autostradă. Harta este reprezentată pe o grilă bidimensională ca o mulțime de puncte, închise într-un contur dreptunghiular. Conturul hărții și obstacolele de pe hartă sunt marcate folosind caracterul având codul ASCII 219. Punctele libere de pe hartă (pe unde poate trece autostrada) sunt marcate prin caracterele având codurile ASCII 176, 177 și 178. Orașele sunt marcate folosind caractere având codul ASCII 1. Există exact două orașe pe hartă. Marcajele pentru puncte libere, orașe și obstacole, pot apărea numai în interiorul conturului hărții; nu există alte marcaje pe hartă.

Un drum între două puncte de pe hartă unește (pe verticală și/sau orizontală) mai multe puncte libere adiacente. Un punct liber al cărui cod ASCII este cod_punct necesită (cod_punct-175) unități pentru construirea părții de autostradă ce trece prin acel punct. Costul asociat orașelor este 0. Lungimea drumului este numărul punctelor sale, incluzând punctele corespunzătoare orașelor. Costul unui drum este suma dintre lungimea drumului și costul fiecărui punct de pe drum. Cel mai bun drum este drumul care are costul minim.

Scrieți un program care, pentru fiecare hartă citită dintr-un fișier text, găsește toate drumurile de cost minim dintre cele două orașe de pe hartă și marchează aceste drumuri folosind caracterul având codul ASCII 32 (spațiu). Toate drumurile trebuie marcate pe aceeași hartă. Orașele își mențin marcajul inițial.

O hartă este citită ca o secvență de linii de text terminată printr-o linie care conține numai liniuțe de subliniere. Există cel mult 30 de linii, incluzând linia care indică terminarea hărții și cel mult 80 de caractere pe fiecare linie. Datele de intrare sunt corecte. Fișierul standard de ieșire conține hărțile cu drumurile marcate. Fiecare hartă este dată la ieșire în același format ca și la intrare, incluzând linia care indică terminarea hărții și este precedată de o linie care indică numărul celor mai bune drumuri și costurile lor (0 dacă nu există drumuri). Numărul celor mai bune drumuri poate fi destul de mare și poate fi reprezentat pe patru cuvinte (8 bytes).

Exemplu:

Intrare: D.DAT

Ȱ±°ČȰȱČČ °°°°±°Č°°±°ČȰ±J

°ČČȰ±Č°°±Čȱ°Č±°±± Čȱ±±°Č±

±Č°°°Č±°Č°±±±ČȰ°°±±±Č±°°Č°°

ȱȰȰȱ°Č ±Č°±Čȱ°Č°Č±

°Č°°±±°±°±ČČȱ± ±±°Č±±°±°Č°Č

°±±°°±Č± ±Č±ČČȰ±Č±Č°±°

J°±Č°±Č± ±°°Čȱ±±°°±°Č°°°°°°

Ieșire: - ecran

Ȱ±°ČȰȱČČ °°°°±°Č°°±°ÛÛÛÛJ

°ČČȰ±Č°°±Čȱ°Č±°±± ČÛÛÛ±°Č±

±Č°°°Č±°Č°±±±ČȰ°°±±±Û±°°Č°°

ȱȰȰȱ°Č ±ČÛÛÛȱ°Č°Č±

°Č°°±±°ÛÛÛÛÛÛ±± ±±°ÛÛ±°±°Č°Č

°±±°°±ÛÛ ±Č±ÛÛÛÛÛÛÛÛ°±°

JÛÛÛÛÛÛ± ±°°Čȱ±±°°±°Č°°°°°°

Intrare: D.DAT

Ȱ±°ČȰȱČȰ°° ȰȰ°±°ČȰ±°Č

ČȰ±Č°°±JČȱ°Č °±±Čȱ±J±°Č±±

Ieșire - ecran

Ȱ±°ČȰȱČȰ°° ȰȰ°±°ČȰ±°Č

ČȰ±Č°°±JČȱ°Č °±±Čȱ±J±°Č±±

P029905: Inversiuni

Fie a1, a2, …, an un șir de n numere distincte. Dacă i<j și ai>aj atunci perechea (i,j) se numește inversiune. De exemplu, în șirul 3, 2, 1, 5, 6, 7, 8, 9 există 3 inversiuni, în timp ce șirul 1, 2, 3, 4 nu are nici o inversiune.

Un fișier text conține șiruri nevide de întregi. Fiecare șir începe cu un număr 1ŁNŁ30000 care specifică numărul de întregi din șir. Acest număr nu face parte din șir. Numerele sunt separate prin caractere albe (spații, tab-uri și caractere de sfârșit de linie). Datele din fișierul de intrare sunt corecte.

Scrieți un program care, pentru fiecare șir de numere din fișierul de intrare, afișează numărul inversiunilor din șir. Fiecare rezultat trebuie afișat pe o linie separată, la ieșirea standard.

Exemplu

Intrare: E.DAT

5

1 2 3 4 5

4

4 3 2 1

1

1000

Ieșire: - ecran

0

6

0

P029906: Rețea de comutatoare

Profesorul MAG a inventat un comutator și l-a propus ca un element de bază în construcția microprocesoarelor. Conectând două astfel de comutatoare și trimițând semnale la intrările specificate și la pinii de control, el poate obține o rețea care poate rezolva orice operație aritmetică sau logică. Pentru a ști dacă această rețea implementează o operație dată, profesorul MAG trebuie să cunoască valorile semnalului, la ieșirile comutatoarelor. Ajutați-l să găsească aceste valori.

Comutatorul desenat în figura 1 are 5 pini: L și D - pinii de intrare, R și U - pinii de ieșire, S - pinul de control. Comutatorul se poate afla în două stări:

1. dacă S = 0 atunci L este conectat cu R și D este conectat cu U (fig. 2);

2. dacă S = 1 atunci L este conectat cu U și D este conectat cu R (fig. 3).

Fig. 1 Fig. 2 Fig. 3

Vom spune că două comutatoare sunt conectate dacă una dintre ieșirile primului comutator este conectată cu intrarea celui de-al doilea comutator. Rețeaua de comutatoare este o conexiune între elementele comutatoarelor.

Rețeaua de comutatoare, semnalele la unele intrări și semnalele tuturor pinilor de control sunt date. Vi se cere să găsiți semnalele la pinii de ieșire specificați, folosind informațiile date.

Intrare: - F.DAT

Structura fișierului de intrare este următoarea:

Pe prima linie este numărul seturilor de date. Următoarea linie începe cu primul set, iar seturile de date sunt separate printr-o linie vidă.

Setul de date are următoarea structură.

- Prima linie a setului de date conține numărul comutatoare lor N, unde NŁ4000 și numărul de conexiuni din rețea K.

- Comutatoarele sunt numerotate de la 0 la N-1. Intrările comutatoarelor au etichetele L și D iar ieșirile au etichetele R și U.

- Următoarele K linii descriu conexiunile dintre comutatoare. Fiecare linie are forma COM1 IEȘIRE COM2 INTRARE separate printr-un spațiu. COM1 și COM2 sunt numere care indică comutatoare, IEȘIRE este o ieșire a comutatorului COM1, INTRARE este o intrare a comutatorului COM2. Ieșirea IEȘIRE a comutatorului COM1 este conectată cu intrarea INTRARE a comutatorului COM2. Numărul COM2 este mai mare decât numărul COM1. Fiecare ieșire a unui comutator poate fi conectată numai la o intrare. Fiecare intrare a unui comutator poate fi conectată numai la o ieșire.

- Urmează o linie vidă.

- Următoarea linie conține N valori pentru semnalele pinilor de control ai comutatoarelor 0, …, N-1. Valorile posibile ale semnalului sunt 0 și 1.

- Urmează o linie vidă.

- Putem trimite un semnal 1 la orice intrare care nu este conectată la o ieșire. Următoarea linie conține numărul SG de semnale cu valoarea 1 trimise intrărilor.

- Urmează SG linii de semnal. Fiecare linie de semnal conține numărul COM al comutatorului și intrarea INTRARE, separate printr-un spațiu. Înseamnă că semnalul cu valoarea 1 este trimis la intrarea INTRARE a comutatorului COM. Dacă intrarea unui comutator nu este conectată cu nici o ieșire și nu a fost trimis un semnal cu valoarea 1 la această intrare vom considera că acest pin este inutil (semnalul la această intrare este 0).

- Urmează o linie vidă.

Aceasta a fost descrierea structurii rețelei. Acum dorim să știm semnalele la pinii de ieșire specificați. Următoarea linie conține numărul de teste NT pentru setul de date curent.

Următoarele NT linii de test au următoarea formă: numărul comutatorului COM și ieșirea IEȘIRE, separate printr-un singur spațiu. Pentru fiecare linie de test trebuie să aflăm semnalul la ieșirea IEȘIRE a comutatorului COM.

Ieșire: - ecran

Ieșirea constă din NPR linii, unde NPR este numărul seturilor de date. Fiecare linie conține NT semnale. Al i-lea număr în linia de ieșire curentă este un semnal la ieșirea IEȘIRE a comutatorului COM pentru al i-lea set de date.

Exemplu:

Figurile următoare prezintă două posibile rețele. Intrările și ieșirile corespunzătoare sunt prezentate mai jos.

Intrare: F.DAT Ieșire: - ecran

2 0 1 0 0

3 3 0 1

0 R 1 L

0 U 2 L

1 U 2 D

1 0 0

1

0 L

4

0 R

2 R

2 U

1 R

1 0

1

1

0 L

2

0 R

0 U

P029907: Combinații

O n-mulțime este o mulțime cu n elemente. O k-combinație a unei n-mulțimi S este o k-submulțime a lui S. De exemplu 3-combinațiile mulțimii {a, b, c, d} sunt {a, b, c}, {a, b, d}, {a, c, d}, {b, c, d}.

Fie Ck mulțimea tuturor șirurilor care reprezintă k-combinațiile literelor din alfabetul englez. Fiecare șir din Ck este ordonat în ordine lexicografică crescătoare. De exemplu, C52 conține șirul:

‘ABCDEFGHIJKLMNOPQRSTUVWXYZ

abcdefghijklmnopqrstuvwxyz' (întregul alfabet).

Fie X un șir nevid format din literele alfabetului englez. Considerând ordinea lexicografică a șirurilor, definim funcțiile inferior și superior după cum urmează:

- inferior(k,X) determină cel mai mare șir din Ck care nu este mai mare decât X; funcția inferior(k,X) nu este definită dacă X este mai mic decât cel mai mic șir din Ck.

- superior(k,X) determină cel mai mic șir din Ck care nu este mai mic decât X; funcția superior(k,X) nu este definită dacă X este mai mare decât cel mai mare șir din Ck.

De exemplu:

inferior(3,AB) este nedefinită,

superior(3,AB)=ABC;

inferior(3,a)=Zyz,

superior(3,a)=abc;

inferior(3,bde)=superior(3,bde)=bde;

inferior(3,xz)=xyz,

superior(3,xz) este nedefinită.

Scrieți un program care citește perechi de valori k X dintr-un fișier text și, pentru fiecare pereche, calculează inferior(k,X) și superior(k,X). Fiecare pereche k X se află pe o linie separată a fișierului text, k este un întreg, 1ŁkŁ52, și X este un șir nevid format din cel mult 52 de litere. Fișierul de intrare conține date corecte.

Pentru fiecare pereche k X de valori, șirurile inferior(k,X) și superior(k,X) sunt afișate pe linii consecutive la ieșirea standard și sunt urmate de o linie vidă. Dacă șirurile inferior(k,X) și superior(k,X) nu sunt definite, vor fi afișate mesajele:

inferior = null, respectiv superior = null.

Exemplu:

Intrare: - G.DAT Ieșire: - ecran

3 AB inferior = null

3 a superior = ABC

3 bde

3 bdeaa inferior = Zyz

3 xz superior = abc

inferior = bde

superior = bde

inferior = bde

superior = bdf

inferior = xyz

superior = null

[cuprins]