Bursele Agora! CONCURSA luat sfârșit și a doua etapă a concursului organizat de Gazeta de Informatică; în acest număr vă prezentăm clasamentul rundei a doua, clasamentul după două etape, soluțiile problemelor propuse la runda a doua, precum și enunțurile celor trei probleme ale rundei a patra.
Erori... Numărul cazurilor în care nu erau respectate specificațiile datelor de intrare sau de ieșire a scăzut mult, dar nu a dispărut complet. Vă rugăm să respectați cu strictețe aceste specificații deoarece, datorită faptului că evaluarea este automată, programul de evaluare va considera că soluția este eronată, chiar dacă, din punct de vedere logic, ea este corectă. Nu a dispărut complet nici eroarea de compilare: Error 116: Must be in 8087 mode to compile this
Dispozitive I/O La toate problemele propuse în cadrul concursului Bursele Agora datele de intrare sunt citite dintr-un anumit fișier, iar datele de ieșire trebuie scrise într-un alt fișier. Din aceste motive nu este nevoie să afișați date pe ecran sau să așteptați date introduse de la tastatură. Programatorii în Pascal sunt rugați să nu mai folosească unit-ul Crt deoarece există probleme la execuția programelor; reamintim faptul că evaluarea se face pe un calculator cu procesor Intel Pentium III, având o frecvență de 450 MHz.
Așteptarea reacției Au existat din nou cazuri în care programele așteptau apăsarea unei taste înaintea terminării execuției. Din punctul de vedere al programului de evaluare, execuția nu se încheie înaintea apăsării acestei taste; acesta va aștepta ca timpul maxim admis pentru execuția testului să expire, după care va întrerupe execuția programului semnalând depășirea timpului admis, iar concurentul nu va primi punctele care i s-ar fi cuvenit pentru testul respectiv.
Runda 2, problema 1 Factorial(formula lui Stirling) Această problemă a fost cauza unor nemulțumiri, deoarece se afirma că necesită cunoștințe matematice superioare. Totuși, concurenții care au trimis rezolvări pentru această problemă au obținut un punctaj mediu de 43.80 puncte. Problema determinării numărului de cifre al lui n! a devenit deja o problemă clasică, ea apărând pentru prima dată la Olimpiada Balcanică de Informatică din 1997, unde a fost propusă de dl. prof. dr. Adrian Atanasiu. O problemă care se reducea la determinarea numărului de cifre a lui n! a fost propusă și în cadrul taberei de pregătire și selecție a Lotului Național de Informatică, organizată la Sinaia în vara acestui an. În funcție de valoarea maximă a numărului n problema admite diferite soluții. La BOI '97 valoarea maximă a fost 30000, deci o soluție foarte bună s-ar fi putut obține folosind formula:
deci numărul de cifre poate fi obținut calculând partea întreagă a sumei logaritmilor primelor n numere naturale la care se adună 1. În cadrul concursului nici unul dintre concurenți nu a rezolvat în acest mod problema, dar au existat mulți care au obținut punctajul maxim. Aceștia au simulat calculul valorii numărului n! astfel: - La fiecare pas (pasul i) se păstrează primele cinci cifre (au existat variante care păstrau până la 9 cifre) și numărul de cifre care urmează. - Numărul format din cele cinci cifre este înmulțit cu numărul i obținându-se un nou număr. - Noul număr este împărțit repetat la 10 până când se obține un număr care are cinci cifre; de fiecare dată când se efectuează o împărțire la 10 va crește numărul cifrelor care urmează după grupul primelor cinci. - În final numărul cifrelor lui n! va fi găsit adunând cinci la grupul cifrelor care urmează după primele cinci cifre. O descriere în pseudocod a algoritmului este: citește n gr5=40320; nrcifre=0 pentru i de la 9 la n execută gr5Źgr5*i cât timp gr5>100000 execută nrcifreŹnrcifre+1; gr5Ź[gr5/10] sfârșit cât timp sfârșit pentru afișează nrcifre+5
Observație Trebuie tratate special cazurile în care n este mai mic decât 8.
La tabăra de pregătire de la Sinaia valoarea maximă a lui n! era 24572457, deci nici una dintre variantele amintite anterior nu furniza soluția în timp util. Cei care au rezolvat atunci problema, au folosit metoda sumei logaritmilor, puțin modificată. Ei au calculat inițial sumele parțiale pentru numerele până la 24572457 și au păstrat într-un tablou de constante rezultatele obținute pentru numerele care erau multipli de 100000. Apoi, folosind acest tablou au determinat numărul de cifre începând însumarea de la o anumită valoare și adunând apoi cel mult 100000 de termeni; acest algoritm s-a încadrat atunci în timp. În cadrul concursului Bursele Agora limita impusă a fost 2000000000, deci folosirea algoritmului anterior a fost destul de dificilă, deoarece execuția unui program care calculează suma logaritmilor primelor 2000000000 de numere naturale durează destul de mult. Totuși au existat și concurenți care au adoptat această soluție; Liviu Andreicuț a păstrat valorile pentru multiplii de 200000, Ileană Ioana pentru cei de 250000, Patcas Csaba a ales multiplii de 500000, iar Andrei Marius George pe cei de 1000000. Majoritatea concurenților au încercat să calculeze suma logaritmilor primelor n numere naturale; evident, o astfel de soluție nu respecta limita de timp de o secundă pentru valori mari ale lui n. Programele respective funcționau numai pentru valori mici ale lui n (cel mult până la 10000000) și au obținut între 20 și 35 de puncte. Totuși soluția cea mai bună ar fost folosirea formulei lui Stirling, prezentată în numărul din decembrie 1999 al Gazetei de Informatică. Vă prezentăm în continuare soluția propusă de Ileana Constantinescu din Sibiu:
Runda 2, problema 2 Spiriduși (combinări în hiperspațiu)Aceasta a fost cea mai ușoară dintre cele șase probleme propuse până acum, media obținută de concurenți fiind de 59.61 puncte. Numărul concurenților care au obținut punctajul maxim a fost destul de redus, mulți obținând numai 95 de puncte. Majoritatea concurenților au folosit metoda programării dinamice pentru a calcula numărul de puncte din spațiu. Construim o matrice p de dimensiuni nŽs în care pij reprezintă numărul de puncte în care poate ajunge GIS într-un hiperspațiu i-dimensional în j zile. Relația de recurență care este foarte ușor de observat este:
Inițial vom completa prima linie și prima coloană a matricei astfel: p1,i=i și pi,1=1. Motivul pentru care o mulțime de concurenți au obținut numai 95 de puncte s-a datorat faptului că pentru unul din test numărul de puncte era de ordinul miliardelor (peste 9000000000) și nu putea fi reprezentat pe patru bytes așa cum au considerat ei. Vă prezentăm în continuare soluția bazată pe această metodă, soluție propusă de Ileana Constantinescu.
Runda 2, problema 3 Submulțimi de sumă datăAceasta a fost cea mai dificilă problemă de până acum, media obținută de concurenți fiind de 21.89 puncte. Acest lucru nu este deloc surprinzător deoarece încă nu se cunoaște un algoritm eficient pentru rezolvarea problemei. Problema submulțimii de sumă dată face parte din clasa problemelor NP-complete, probleme a căror soluție poate fi verificată în timp polinomial, dar pentru care nu se cunoaște un algoritm de rezolvare în timp polinomial. Până în momentul de față cercetătorii nu au reușit să găsească o limită inferioară pentru complexitatea algoritmilor care rezolvă astfel de probleme, deci încă nu s-a demonstrat faptul că există numai algoritmi exponențiali pentru rezolvarea unei astfel de probleme. Teoria NP-completitudinii este foarte interesantă, obținându-se până acum câteva rezultate foarte interesante; totuși ne oprim aici deoarece nu este necesară prezentarea acesteia. Datorită faptului că încă nu s-a descoperit un algoritm eficient pentru rezolvarea acestei probleme (în cazul general - așa cum a fost propusă spre rezolvare în cadrul concursului GInfo) nimeni nu se aștepta să apară o soluție corectă. Pentru rezolvarea acceptabilă a unei astfel de probleme trebuie folosiți algoritmi de aproximare (eventual probabiliști) care să determine o soluție cât mai apropiată de cea corectă. Acesta a fost și motivul pentru care redacția a hotărât să acorde și punctaje parțiale pentru această problemă. Singurul concurent care a obținut punctaj maxim la această problemă a fost Valentin Muste din Baia Mare; programul său a furnizat rezultatul corect pentru cinci dintre cele zece teste și rezultate foarte apropiate în rest, punctajul real fiind de 99.949 puncte. Vă prezentăm în continuare soluția acestui concurent: [cuprins] |