B1 - Pangram
Vremensko ograničenje | Memorijsko ograničenje |
---|---|
1000ms | 512MB |
Moreplovac Brle je u jednoj od svojih pustolovina nabasao na novo, neotkriveno ostrvo. Kada je pokušao da priđe ostrvu ugledao je rečenicu ispisanu ogromnim slovima u pesku. Nažalost, palmini listovi prekrivaju delove plaže, pa neki delovi rečenice nisu vidljivi. Poznato je da je ispisana rečenica savršen pangram (sadrži svako slovo engleske abecede tačno jednom) i sastoji se isključivo od slova engleske abecede i razmaka. Pritom, ne postoje dva susedna razmaka, i rečenica ne počinje niti se završava razmakom. Vaš zadatak je da pomognete Brletu da rekonstruiše ispisanu rečenicu, ukoliko je to moguće.
Opis ulaza
U prvoj liniji standardnog ulaza nalazi se broj \(N\). U drugoj liniji standardnog ulaza nalazi se string \(A\) dužine \(N\), koji predstavlja ispisanu rečenicu iz Brletove perspektive. Pritom važi:
- \(A\) se sastoji isključivo od slova engleske abecede (slova iz skupa \(\{a \dots z\}\)), karaktera _ koji označavaju razmake, i karaktera \(?\) koji označavaju palmine listove tj. karaktere (slova ili razmake) koji nisu vidljivi.
- U \(A\) ne postoje dva susedna razmaka, a ni prvi i poslednji karakter \(A\) nisu razmaci.
Opis izlaza
U prvom i jedinom redu standardnog izlaza ispisati string \(B\), koji predstavlja rekonstruisanu rečenicu. Pritom mora da važi:
- \(B\) se sastoji isključivo od slova engleske abecede i karaktera _ koji označavaju razmake.
- U \(B\) ne postoje dva susedna razmaka, a ni prvi i poslednji karakter \(B\) nisu razmaci.
- \(B\) je savršen pangram.
- Moguće je dobiti \(B\) od \(A\) isključivo nizom zamena karaktera \(?\) slovima engleske abecede ili razmacima.
Ukoliko ima više rešenja, ispisati bilo koje. Ukoliko takvo \(B\) ne postoji (tj. rekonstrukcija nije moguća) Brle sanja i potrebno je ispisati string SAN
(velikim slovima).
Primer 1
Ulaz
Izlaz
Primer 2
Ulaz
Izlaz
Objašnjenje primera
U prvom primeru možemo pretpostaviti da prva serija palminih listova prekriva karaktere \(dfe\_\), druga \(u\_v\), a treća \(w\). Ovako dobijamo savršen pangram koji ispunjava sve uslove.
U drugom primeru je nemoguće zameniti tri palmina lista karakterima tako da se dobije savršen pangram koji ispunjava sve uslove, pa je u pitanju san.
Ograničenja
- \(1 \leq N \leq 250\).
Test primeri su podeljeni u pet disjunktnih grupa:
- U test primerima koji vrede 15 poena važi \(1 \leq N \leq 26\).
- U test primerima koji vrede 15 poena nema palminih listova.
- U test primerima koji vrede 15 poena postoji najviše jedan karakter prekriven palminim listom.
- U test primerima koji vrede 15 poena cela rečenica je prekrivena palminim listovima.
- U test primerima koji vrede 40 poena nema dodatnih ograničenja.
Autor | Tekst i test primeri | Analiza rеšenja | Testiranje |
---|---|---|---|
Dušan Zdravković | Nikola Jovanović | Nikola Jovanović | Dimitrije Erdeljan |
Označimo broj pojavljivanja karaktera ? u stringu \(A\) sa \(U\), a skup slova engleske abecede koja se ne pojavljuju u stringu \(A\) sa \(S\). Jednim prolaskom kroz string možemo lako naći ove vrednosti. Ukoliko se neko slovo pojavljuje više od jednom možemo odmah zaključiti da rekonstrukcija nije moguća i prekinuti izvršavanje programa.
Sada znamo da treba zameniti tačno \(|S|\) karaktera ? slovima engleske abecede kako bi dobijena rečenica bila savršen pangram. Kako moramo zameniti sve karaktere ?, sledi da treba zameniti tačno \(R=U-|S|\) njih razmacima. Pritom, ako važi \(U < |S|\) nije moguće dodati sva nedostajuća slova, pa je ovo još jedan slučaj u kom zaključujemo da rekonstrukcija nije moguća.
Ostalo je još izvršiti samu rekonstrukciju tj. rasporediti slova i razmake. Treba imati u vidu da nije svejedno na koji način ovo radimo. Na primer, ako prvo dodamo svih \(|S|\) slova (tj. zamenimo prvih \(|S|\) karaktera ? slovima) možda neće biti moguće postaviti svih \(R\) razmaka (npr. zbog uslova da dva razmaka ne smeju biti susedi). Primetimo da je uvek moguće dodati slovo, ali nije uvek moguće dodati razmak. Stoga, vršićemo rekonstrukciju tako da greedy dodajemo razmake dok ne dodamo svih \(R\). Drugim rečima, krećemo se kroz string \(A\) sa leva na desno, i na svakoj poziciji postavljamo razmak ukoliko su svi uslovi ispunjeni: na toj poziciji je karakter ?, nismo na početku/kraju stringa, nijedan od dva susedna karaktera nije razmak. U suprotnom, dodajemo jedno od nedostajućih slova iz skupa \(S\). Kada na ovaj način dodamo svih \(R\) razmaka, sve preostale karaktere ? menjamo preostalim nedostajućim slovima iz skupa \(S\) i ispisujemo dobijeni string kao rešenje zadatka. Nije teško pokazati da se na ovaj način može dodati maksimalan broj razmaka, te da ukoliko ovakva procedura nije u stanju da doda svih \(R\), došli smo do trećeg i poslednjeg slučaja u kom je nemoguće izvršiti rekonstrukciju.