Iza nas je prvo kolo Ljetne lige C++,
Nakon evaluacije, uslijedila je "neslužbena" analiza programskih rješenja, a primjećeni su dosta zanimljivi pristupi.
Posebno nam se dopao sljedeći programski isječak (zadatak VEESAH):
k=(zb1+zb2)%10; if (k==1) cout<<"9"; if (k==2) cout<<"8"; if (k==3) cout<<"7"; if (k==4) cout<<"6"; if (k==5) cout<<"5"; if (k==6) cout<<"4"; if (k==7) cout<<"3"; if (k==8) cout<<"2"; if (k==9) cout<<"1";
Koji bi algoritamski preveli kao:
ako je ostatak 1, ispiši 9 ako je ostatak 2, ispiši 8 ako je ostatak 3, ispiši 7 ako je ostatak 4, ispiši 6 ako je ostatak 5, ispiši 5 ako je ostatak 6, ispiši 4 ako je ostatak 7, ispiši 3 ako je ostatak 8, ispiši 2 ako je ostatak 9, ispiši 1
ili skraćeno:
1 -> 9 2 -> 8 3 -> 7 4 -> 6 5 -> 5 6 -> 4 7 -> 3 8 -> 2 9 -> 1
Ovaj dio sada postaje zanimljiv, kada zamijenimo -> sa + i zapišemo rezultate:
1 + 9 = 10 2 + 8 = 10 3 + 7 = 10 4 + 6 = 10 5 + 5 = 10 6 + 4 = 10 7 + 3 = 10 8 + 2 = 10 9 + 1 = 10
Iz priloženog vidimo da su broj u uvjetu te broj koji se ispisuje međusobno inverzni "po 10", drugim riječima ovih 10 provjera se može napisati kao:
k=(zb1+zb2)%10; cout << 10 - k;
Međutim u samom zadatku, tražena znamenka X može biti i nula! Što u ovom isječku nije predviđeno i tu su nažalost izgubljeni bodovi, dakle nadopuna u stilu tog isječka bi izgledala ovako:
k=(zb1+zb2)%10; if (k==0) cout<<"0"; if (k==1) cout<<"9"; if (k==2) cout<<"8"; if (k==3) cout<<"7"; if (k==4) cout<<"6"; if (k==5) cout<<"5"; if (k==6) cout<<"4"; if (k==7) cout<<"3"; if (k==8) cout<<"2"; if (k==9) cout<<"1";
a kraća verzija bi shodno tome izgledala ovako:
if (k==0)
cout << "0";
else
cout << 10 - k;
Međutim čak ni ta provjera nije potrebna! Zato što vrijedi da je 10%10 == 0, a D%10 == D (gdje je D jedna znamenka).
Stoga je kraće rješenje:
k=(zb1+zb2)%10; cout << (10 - k)%10;
A može i jednolinijsko (bez nepotrebnih uvođenja novih varijabli):
cout << (10 - ( (zb1+zb2) % 10 ) ) % 10;
Voila! Eto i formule za izračun znamenke X ! To isto bi algoritamski preveli kao:
Ispiši zadnju znamenku 10-inverza od zadnje znamenke sume zb1+zb2.
—
Od ostalih "gluparijica", primjećene su sljedeće, koje su izgleda neizbježne, ali i pomalo simpatične 🙂
1) Određeni natjecatelji jednostavno ne žele završiti ispis u novom retku… Nekako im uvijek smeta taj cout << endl; na kraju
2) Famozni system("pause"); kod pojedinaca nikako ne dopušta da se ispred njega nađu dva slasha (//) …
3) Zanimljivo je da u trećem zadatku postoji ishod u kojem se ispisuje konstanta "Broj kartice je ispravan.", doduše u veoma rijetkom slučaju (1/10 test primjera), ali samo se mali broj natjecatelja (koji nisu pristupili stvarnom rješavanju) dosjetio to ispisati i pokupiti besplatnih 10 bodova! 🙂 Dakle ipak se isplati barem pogledati test primjere, iako se zadatak čini teškim…
4) I dalje se susrećemo sa slučajevima pogrešno formatiranih ispisa, (npr. umjesto razmaka se ispisuje novi redak ) što može znatno usporiti evaluaciju (da ne kažemo da automatska evaluacija vjerojatno ne bi ni prošla )
5) Nažalost C++ još uvijek ne podržava 16-znamenkaste integere, pa bi provjera tipa (x == 1234567890123456) rezultirala sa compile error, što se nažalost i dogodilo u jednom slučaju… Bilo bi korisno se podsjetiti koji je raspon integera od 4B ili doublea od 8B ?
Sve u svemu, iza nas je jedno uspješno kolo i puno sreće u nadolazećim!
Autor zadataka C++ kadeti.
