V praktických úlohách P-I-1, P-I-2 a P-I-3 je třeba k řešení připojit odladěný program zapsaný v jazyce Pascal, C nebo C++. Program se odevzdává v písemné formě (jeho výpis je tedy součástí řešení) i na disketě, aby bylo možno otestovat jeho funkčnost. Slovní popis řešení musí být ovšem jasný a srozumitelný i bez toho, že by bylo nutno nahlédnout do zdrojového textu programu. V úloze P-I-4 je třeba navrhnout a zapsat odpovídající dlaždicové programy.
P-I-1 Stromy
Binární strom je struktura tvořená jednotlivými uzly. Jeden z uzlů je význačný
- říkáme mu kořen. Každý z uzlů buď nemá žádného následníka (pak se nazývá
list) nebo má právě dva následníky (další uzly stromu). Hloubkou uzlu rozumíme
jeho vzdálenost od kořene stromu. Uvědomte si, že kořen může být i listem -
pak je binární strom tvořen jediným vrcholem hloubky 0. Příklad binárního
stromu si můžete prohlédnout na následujícím obrázku:
Abychom mohli binární stromy jednoduše popisovat, zavedeme si následující kódování:
k-tý řádek kódování (pro k=0,1,2,...) popisuje právě uzly hloubky k v pořadí zleva doprava. Uzel binárního stromu, který není listem, budeme v našem kódování zobrazovat znakem U
, listy budeme označovat znakem L
. Binární strom z předchozího obrázku tedy bude zakódován jako:
UU
LULL
LL
STROMY.IN
obsahuje jediné číslo N (počet listů). Druhý řádek obsahuje N čísel - hloubky listů hledaného stromu.
STROMY.OUT
bude obsahovat kódování nalezeného stromu ve výše uvedeném formátu, případně zprávu Odpovidajici strom neexistuje.
.
STROMY.IN
STROMY.OUT
STROMY.IN
STROMY.OUT
POSEL.IN
obsahuje
čísla N (počet měst) a M (počet cest). Po něm následuje M řádků, z nichž
každý obsahuje popis jedné cesty. Cesta je popsána dvojicí čísel koncových
měst. Následuje řádek s číslem K (počet obsazených měst) a za ním K
řádků s čísly obsazených měst. Poslední řádek vstupního souboru obsahuje číslo města, odkud vyjíždí posel, a číslo města, kde dlí generál.
POSEL.OUT
jsou čísla
měst na nejlepší nalezené trase uvedená v pořadí, v jakém jimi má posel projíždět. Všechna čísla měst jsou zapsána na jediném řádku výstupního souboru a jsou oddělena mezerami.
POSEL.IN
POSEL.OUT
Celková délka naplánované trasy je L (1<=L<=1000000000). Maximální vzdálenost, kterou naši přátelé mohou urazit za jeden den, je K, tj. ve dvou po sobě následujících dnech musí přespat v kempech vzdálených nejvýše o K. Na naplánované trase se nachází celkem N kempů (0<=N<=10000); i-tý kemp je ve vzdálenosti li od začátku jejich výletu a cena za přespání v něm je ci (1<=ci<=20000). Čísla L, K, li a ci jsou celá kladná; všechna li jsou navzájem různá a platí 0<l1<l2<...<lN<L.
Vaším úkolem je rozhodnout, zda skupina může naplánovanou trasu projet. Pokud lze trasu takto projet, pak určete, ve kterých kempech mají přespat tak, aby:
VYLET.IN
. Na prvním řádku jsou čísla L,
K a N oddělená mezerou. Na dalších N řádcích následují dvojice
čísel li a ci oddělených mezerou, postupně pro i=1 až i=N.
vylet-a.out
pro úlohu a) a vylet-b.out
pro
úlohu b). Na prvním řádku je věta Trasu nelze projet.
, pokud výlet
nelze uskutečnit tak, aby naši přátelé nikdy neujeli za den vzdálenost
větší než K. V opačném případě první řádek obsahuje dvě čísla - M
a C. První z nich, M (0<=M), je počet kempů, ve kterých skupina
přespí, druhé z nich, C, je cena, kterou za přespání v těchto
kempech zaplatí. Druhý řádek souboru obsahuje M mezerou oddělených
čísel kempů, v nichž naši přátelé budou nocovat.
Kempy jsou číslovány od jedné. Pokud je M=0, nemusí být druhý řádek
vůbec uveden. V případě, že existuje
více řešení splňujících podmínku a) nebo b), program může vypsat
libovolné jedno z nich.
VYLET.IN
VYLET-A.OUT
VYLET-B.OUT
VYLET.IN
VYLET-A.OUT
a VYLET-B.OUT
VYLET.IN
VYLET-A.OUT
a VYLET-B.OUT
ano
nebo ne
: sestavíme vhodnou množinu typů dlaždic (ta je
pro daný problém pevná - nezávisí na vstupu), vezmeme
vhodně velkou zeď, její horní okraj obarvíme podle vstupu našeho problému,
ostatní okraje ponecháme jednobarevné a budeme se ptát, zda je tuto zeď
možno vydláždit či nikoliv. Přitom chceme, aby tento výsledek byl
shodný s řešením naší úlohy.Abychom se nemuseli zabývat tím, jak přesně velkou zeď máme zvolit pro ten či onen vstup úlohy, budeme šířku zdi volit vždy stejnou, jako je délka vstupu (horní okraj tedy bude celý zaplněn vstupem), zatímco výšku zdi použijeme nejmenší, pro níž existuje vydláždění s použitím naší sady dlaždic.
Když tento způsob počítání srovnáme s klasickým programováním, zjistíme, že zvolená sada dlaždic tvoří v našem modelu něco podobného programu a potřebná výška zdi vzdáleně odpovídá době běhu výpočtu - budeme se proto snažit, aby u našich řešení byla co nejmenší.
Formálně řečeno, dlaždicový program je uspořádaná čtveřice D=(T,l0,p0,d0),
kde T je konečná množina typů dlaždic {(l1,p1,h1,d1),...,
(lk,pk,hk,dk)} a l0, p0 a d0
jsou okrajové barvy. Rozhodovací úlohou P(x) rozumíme úlohu
zjistit, zda vstup x (konečná posloupnost symbolů, resp. barev z předem
určené konečné množiny) má požadovanou vlastnost P. Říkáme, že dlaždicový
program řeší rozhodovací úlohu P(x), jestliže platí,
že P(x)=ano
právě tehdy, když existuje v>0
takové, že je možno vydláždit dlaždicemi typů obsažených v množině T
zeď velikosti |x| x v s horní hranou obarvenou
vstupem x a levou, pravou a dolní hranou obarvenou po řadě barvami
l0, p0 a d0. Od každého typu je možno použít libovolně mnoho
dlaždic. Složitostí programu D pro daný vstup x nazveme nejmenší v, pro něž
to je možné; pokud takové neexistuje, a tedy P(x)=ne
,
definujeme složitost jako nulovou. Složitost programu je funkce délky
vstupu n, jejíž hodnota udává maximum ze složitostí programu pro jednotlivé
vstupy této délky.
Především si ověříme, že každá zeď, kterou je možno vydláždit dlaždicemi
typů z množiny T, má jednotkovou výšku. To jasně plyne z toho, že spodní hrana
každé dlaždice je obarvena plným kolečkem, která se nevyskytuje na žádné horní
hraně. Z téhož důvodu se dlaždice mající na své pravé
hraně prázdné kolečko musí vyskytovat těsně u pravého okraje zdi a nikde jinde.
Každé korektní dláždění proto musí vypadat takto:
což je ovšem možné právě tehdy, když 0<=x1<=x2<=...<=xn-1<=xn, tedy když
posloupnost na vstupu je neklesající.