1. Úvod do předmětu BI-EP2 Efektivní programování 2 LS 2017/2018 Ing. Martin Kačer, Ph.D. 2011-18 Martin Kačer Katedra teoretické informatiky Fakulta informačních technologií České vysoké učení technické v Praze Vznik předmětu byl podpořen FRVŠ v rámci projektu 2581/2011
První hodina obsah Předmět a jeho organizace Vyhodnocovací systém O řešení úloh Znáte už EP1? Mnoho věcí se dnes bude opakovat Martin Kačer, BI-EP2 1. Úvod do předmětu 2
O předmětu
Účel Praktické procvičení algoritmů aneb jak psát programy Rychle Přehledně Efektivně Bez chyb (pokud možno ) Předpokládáme znalosti z BI-AG1 (BI-AG2?) Martin Kačer, BI-EP2 1. Úvod do předmětu 4
Naše cíle Naučit se programovat odstraňovat chyby (ještě lépe: nedělat) přemýšlet!!! Do budoucna Zlepšit výsledky ČVUT (FIT) v soutěžích Martin Kačer, BI-EP2 1. Úvod do předmětu 5
ACM Contest International Collegiate Programming Contest (ICPC) Prestižní soutěž v programování Statisíce studentů 2736 univerzit 102 zemí ze 6 kontinentů Týmová Martin Kačer, BI-EP2 1. Úvod do předmětu 6
ACM ICPC x BI-EP2 Příklady ze soutěže Formát použitý v soutěži (ale nikoli v týmech) Cílem rozhodně není jen ICPC Algoritmy jsou obecné Martin Kačer, BI-EP2 1. Úvod do předmětu 7
Kontakty Martin Kačer Martin.Kacer@fit.cvut.cz Webové stránky pro předmět https://edux.fit.cvut.cz/courses/bi-ep2/ http://judge.fit.cvut.cz:8080/ep/ Další odkazy http://acm.uva.es/ http://contest.felk.cvut.cz/ Martin Kačer, BI-EP2 1. Úvod do předmětu 8
Organizace
Forma Především řešení konkrétních úloh Rozsah 2+1 (oficiálně 2+2) Každý týden hodina od 9:15 Od 11:00 rezerva + konzultace Řešení úloh doma (to především!) => Primárně cvičení od 9:15 Martin Kačer, BI-EP2 1. Úvod do předmětu 10
Čtrnáctidenní cyklus První týden (pátek 9:15) Obecné postupy a algoritmy Zadání na další týden Druhý týden (pátek 9:15) Ukázka řešení problémů Diskuze nad variantami Konzultace v případě potřeby (11:00) Martin Kačer, BI-EP2 1. Úvod do předmětu 11
Řešení úloh první týden Samostatné řešení Zkoušíme, co kdo zvládne sám Nácvik bezchybného návrhu Co smíte? Hledat na internetu OBECNÉ věci a algoritmy Co nesmíte? Hledat konkrétně daný příklad Opisovat Radit se s kolegy (ani se mnou ) Martin Kačer, BI-EP2 1. Úvod do předmětu 12
Řešení úloh druhý týden Implementace podle řešení Dokončení úloh, které jste nezvládli (nestihli) Nácvik bezchybné implementace Co smíte? Hledat na internetu cokoli Radit se s kolegy či se zeptat vyučujícího Studovat prezentaci řešení, vstupy, výstupy Co nesmíte? Úplně to opsat Martin Kačer, BI-EP2 1. Úvod do předmětu 13
Hrajte fér! Samostatně Nepovinný výběrový předmět Poctivě, zejména v prvním týdnu Internet pro obecné hledání ANO Internet pro konkrétní řešení NE! Internet pro zjištění vstupů NE! Porušení pravidel = okamžitý konec! Martin Kačer, BI-EP2 1. Úvod do předmětu 14
Hodnocení I 20 úloh 5 tematických cyklů x 4 úlohy v každém Body za vyřešení 5 bodů v prvním týdnu (max. 5x20 = 100) 3 body v druhém týdnu Body za počet úloh 1 bod za 2 a více úloh v daném cyklu (max. 5) -1 bod za 1 úlohu -2 body za 0 úloh Martin Kačer, BI-EP2 1. Úvod do předmětu 15
Hodnocení II Vlastní vyrobená úloha max. 15 bodů povinná podmínka zápočtu! 3 body subjektivní hodnocení úlohy 7 bodů faktická správnost 5 bodů vzájemné hodnocení Teoretické maximum: 120 bodů Standardní klasifikace A 90 b. B 80 b. C 70 b. atd. Martin Kačer, BI-EP2 1. Úvod do předmětu 16
Harmonogram (změna vyhrazena) #T Datum Náplň 1 23.2. Úvod + vyhodnocovací systém, ladění chyb 2 2.3. Mřížky & Vyplňování 3 9.3. Řešení + konzultace 4 16.3. Prohledávání grafů & Stavový prostor 5 23.3. Řešení + konzultace 7 6.4. Pokrytí & Nejkratší cesty & Kostry 8 13.4. Řešení + konzultace 9 20.4. >>> výuka odpadá <<< 10 27.4. Toky v sítích & Párování 11 4.5. Řešení + konzultace 12 11.5. Řetězce & Geometrie 13 18.5. Řešení + konzultace Martin Kačer, BI-EP2 1. Úvod do předmětu 17
Vyhodnocovací systém
Vyhodnocovací systém PCSS Vyvinut na ČVUT Použit v pražských kolech Webové rozhraní C/C++ Java Martin Kačer, BI-EP2 1. Úvod do předmětu 19
Obdržíte mailem PCSS hesla Platná celý semestr Martin Kačer, BI-EP2 1. Úvod do předmětu 20
PCSS zadání úloh PROBLEMS Martin Kačer, BI-EP2 1. Úvod do předmětu 21
PCSS odevzdání řešení Martin Kačer, BI-EP2 1. Úvod do předmětu 22
PCSS zjištění výsledku Martin Kačer, BI-EP2 1. Úvod do předmětu 23
PCSS možné odezvy Jen pro poslední pokus! compile error program nejde přeložit runtime error chyba za běhu time limit exceeded pomalé/cyklí se wrong answer špatná odpověď presentation error asi chyba formátu accepted úspěšně odevzdáno Martin Kačer, BI-EP2 1. Úvod do předmětu 24
PCSS výsledky ostatních Martin Kačer, BI-EP2 1. Úvod do předmětu 25
Shrnutí: C Funkce main musí vracet nulu Nepoužívat dvoulomítkové komentáře Každá funkce má svůj hlavičkový soubor Neposílat signály (i např. funkce abort, assert) Martin Kačer, BI-EP1 1. Práce s vyhodnocovacím systémem 26
Shrnutí: C++ Funkce main musí vracet nulu Každá funkce má svůj hlavičkový soubor Neposílat signály (např. funkce abort, assert) U dlouhých vstupů pozor na pomalost streamů Martin Kačer, BI-EP1 1. Práce s vyhodnocovacím systémem 27
Shrnutí: Java Název třídy musí přesně odpovídat úloze Default package Všechno uvnitř jedné třídy Případné dodatečné třídy jako vnitřní (!!) U dlouhých vstupů pozor na pomalost Scanneru Martin Kačer, BI-EP1 1. Práce s vyhodnocovacím systémem 28
Potíže s PCSS? Neposílejte řešení opakovaně Obvykle je to zbytečné Sbíráte trestné minuty Ozvěte se! (týká se technických problémů, nikoli potíží s řešením úloh v prvním týdnu) Martin Kačer, BI-EP2 1. Úvod do předmětu 29
Vstup a výstup v PCSS VŽDY pouze standardní stdin, stdout, scanf, printf System.in, System.out i kdyby zadání tvrdilo něco jiného! Otevírání souborů je zakázáno!! Spouštění z příkazové řádky./program < vstup.in > vystup.out Martin Kačer, BI-EP2 1. Úvod do předmětu 30
O řešení úloh
Jaké chceme řešení Správné Vždycky správné! Stabilní Efektivní Rychle hotové!!! V JEDNODUCHOSTI JE SÍLA!!! Martin Kačer, BI-EP2 1. Úvod do předmětu 32
V čem spočívá jednoduchost Zbytečně nepsat Zbytečně nepočítat Co nejméně speciálních případů Ale na žádný nezapomenout! Přehlednost Martin Kačer, BI-EP2 1. Úvod do předmětu 33
Jednoduché = dobré Rychle napsané Přehledné Méně chyb Často efektivnější ale samozřejmě ne vždy => Preferujeme jednoduché Martin Kačer, BI-EP2 1. Úvod do předmětu 34
Přemýšlejme! První nápad nemusí být nejlepší První nápad nemusí být ani správný Proč to děláme zrovna tak? Kdy to (ne)bude fungovat? Výhoda automatického hodnocení Neřekne nám, proč je to špatně Martin Kačer, BI-EP2 1. Úvod do předmětu 35
Správnost algoritmu NELZE stoprocentně otestovat Nechceme zkoušet a DOUFAT Chceme VĚDĚT!!! Dokážete zdůvodnit volbu řešení? Umíte dokázat správnost? Bude to fungovat opravdu VŽDY? Martin Kačer, BI-EP2 1. Úvod do předmětu 36
Efektivita x velikost vstupu Předpokládáme cca miliardy operací Hranice samozřejmě není ostrá Složitost Omezení na data O(n) ~ 1 000 000 000 O(n. log n) ~ 50 000 000 O(n 2 ) ~ 50 000 O(n 3 ) ~ 1 000 O(n 4 ) ~ 200 O(2 n ) ~ 30 O(n!) ~ 10 Martin Kačer, BI-EP2 1. Úvod do předmětu 37
Typické postupy
Povaha úloh Textové zadání Přesně popsaný vstup a výstup Nutno dodržovat Automatické vyhodnocování Úkolem je program, který správně řeší jakoukoli instanci problému! Martin Kačer, BI-EP2 1. Úvod do předmětu 39
Vícenásobné zadání Vstup s jediným příkladem V našich úlohách asi nebude Na začátku zadán počet příkladů Ukončení vstupu Konec souboru Speciální hodnota Martin Kačer, BI-EP2 1. Úvod do předmětu 40
Zpracování při známém počtu N Příklad 1 Příklad 2 Příklad N int n = readnumber(); for (int i = 0; i < n; ++i) { readoneproblem(); solveoneproblem(); printoneproblem(); } Martin Kačer, BI-EP2 1. Úvod do předmětu 41
Zpracování s detekcí konce A1 B1 A2 B2 0 0 for (;;) { int a = readnumber(), b = readnumber(); if (a == 0 && b == 0) break; solveoneproblem(a, b); printoneproblem(); } Martin Kačer, BI-EP2 1. Úvod do předmětu 42
Typické čtení v C/C++ Hodnoty oddělené mezerami - scanf Čísla Znaky Řetězce scanf( %d, &num); scanf( %d%d%d, &num1, &num2, &num3); scanf( %c%c, &char1, &char2); scanf( %s, string); /* proč tam není &string? */ /* proč se v normálních programech nepoužívá? */ Martin Kačer, BI-EP2 1. Úvod do předmětu 43
Čtení v C možné potíže Jaký je rozdíl v těchto zápisech? scanf( %d%d, &num1, &num2); scanf( %d %d, &num1, &num2); scanf( %d%d\n, &num1, &num2); scanf( %d%d, &num1, &num2); scanf( %c%c, &ch1, &ch2); scanf( %d%d, &num1, &num2); scanf( %i%i, &num1, &num2); Martin Kačer, BI-EP2 1. Úvod do předmětu 44
Čtení v C whitespace Přeskakování mezer Je-li zadána mezera Většina konverzí (kromě %c!!) 2 5 ABCDE FGHIJ 2 5 ABCDE FGHIJ scanf( %d%d, &num1, &num2); scanf( %c%c, &ch1, &ch2); ch1 ch2 newline! A scanf( %d%d\n, &num1, &num2); scanf( %c%c, &ch1, &ch2); ch1 ch2 A B Martin Kačer, BI-EP2 1. Úvod do předmětu 45
Čtení v C whitespace Přeskakování mezer Je-li zadána mezera Většina konverzí (kromě %c!!) 2 5 *** * * * 2 5 *** * * * scanf( %d%d, &num1, &num2); scanf( %c%c, &ch1, &ch2); ch1 ch2 newline mezera scanf( %d%d\n, &num1, &num2); scanf( %c%c, &ch1, &ch2); ch1 * ch2 * Martin Kačer, BI-EP2 1. Úvod do předmětu 46
Čtení v C whitespace Přeskakování mezer Je-li zadána mezera Většina konverzí (kromě %c!!) 3 7 scanf( %d%d, &num1, &num2); num1 3 num2 7 3 7 scanf( %c%c, &ch1, &ch2); ch1 3 ch2 mezera! Martin Kačer, BI-EP2 1. Úvod do předmětu 47
Čtení v C formát čísel V desítkové soustavě vždy %d!! i když je to obvykle jedno 12:05 08:45 scanf( %d:%d, &num1, &num2); scanf( %d:%d, &num3, &num4); num1 12 num2 5 num3 8 num4 45 08:45 scanf( %i:%i, &num3, &num4); num3 0 num4 nedefinováno! Martin Kačer, BI-EP2 1. Úvod do předmětu 48
Typické čtení Java Použití třídy java.util.scanner Není příliš efektivní import java.util.scanner; Scanner in = new Scanner(System.in); int count = in.nextint(); in.nextline(); double d = in.nextdouble(); Martin Kačer, BI-EP2 1. Úvod do předmětu 49
Alternativní čtení Java O něco málo složitější, ale rychlejší StringTokenizer st = new StringTokenizer(""); BufferedReader input = new BufferedReader( new InputStreamReader(System.in)); String nexttoken() throws Exception { while (!st.hasmoretokens()) st = new StringTokenizer(input.readLine()); return st.nexttoken(); } int nextint() throws Exception { return Integer.parseInt(nextToken()); } Martin Kačer, BI-EP2 1. Úvod do předmětu 50
Čtení po řádcích C/C++ gets / fgets / getchar Uloží i newline!! Pozor na kombinaci se scanf! 2 ABCDE FGHIJ 2 ABCDE FGHIJ scanf( %d\n, &num); fgets(string, length, stdin); num 2 string ABCDE scanf( %d, &num); fgets(string, length, stdin); num 2 string prázdný! Martin Kačer, BI-EP2 1. Úvod do předmětu 51
Čtení po řádcích Java Pro změnu asi o něco jednodušší BufferedReader StringTokenizer st = new StringTokenizer(""); BufferedReader input = new BufferedReader( new InputStreamReader(System.in)); String nextline() throws Exception { return input.readline(); } Martin Kačer, BI-EP2 1. Úvod do předmětu 52
Formátování výstupu
Desetinná čísla Daný počet desetinných míst Zaokrouhlování 3.1415926535 3.14 3.142 42 42.000 Martin Kačer, BI-EP2 1. Úvod do předmětu 54
printf Reálná čísla C/C++ printf( %f, pi); 3.141593 printf( %.2f, pi); 3.14 printf( %0.3f, pi); 3.142 printf( %.3f, 0.25); 0.250 printf( %8.3f, 0.25); 0.250 printf( %08.3f, 0.25); 0000.250 Martin Kačer, BI-EP2 1. Úvod do předmětu 55
Reálná čísla Java java.text.* MessageFormat, NumberFormat, DecimalFormat out.println(new DecimalFormat("0").format(pi)); println(pi); 3.141592653589793 DecimalFormat( 0 ); 3 DecimalFormat( 0.000 ); 3.142 DecimalFormat( 000.000 ); 003.142 DecimalFormat( ###.### ); 3.142 DecimalFormat( 0.000 ); 42.250 DecimalFormat( #.### ); 42.25 Martin Kačer, BI-EP2 1. Úvod do předmětu 56
Složitější formátování Požadavky na přesné rozmístění mezery, ASCII-art apod. $ $$$$$ ############ $$ $ $$ # B # $$ $ # ### # # 2 2 2 $$$$$ # #X #--# c = a + b $ $$ # ###### # $$ $ $$ # A # 00# $$$$$ ############ $ Martin Kačer, BI-EP2 1. Úvod do předmětu 57
Složitější formátování Požadavky na přesné rozmístění Většinou se vyplatí zapisovat do pole char map[20][61]; for (r = 0; r < 20; ++r) { for (c = 0; c < 60; ++c) map[r][c] = ; map[r][60] = \0 ; } while(...) map[i][j] = - ; map[i+1][j] = ; C / C++ Martin Kačer, BI-EP2 1. Úvod do předmětu 58
Složitější formátování Požadavky na přesné rozmístění Pole pak vypíšeme celé najednou char map[20][60];... for (r = 0; r < 20; ++r) printf( %s\n, map[r]); C / C++ char ch[][] = new char[20][30];... for (int i = 0; i < 20; ++i) System.out.println(ch[i]); Martin Kačer, BI-EP2 1. Úvod do předmětu 59
Reálná aritmetika
Reálná čísla Reprezentace: mantisa + exponent => rozlišuje jen určitý počet platných číslic 314159265358979000000000000000000000000 OK 0,00000000000000000000000314159265358979 OK ale při součtu se přesnost ztratí! Desetinná čísla jsou navíc nepřesná sama o sobě: 0,125 desítkově 0,001 binárně 0,2 desítkově 0,001100110011 binárně Martin Kačer, BI-EP2 1. Úvod do předmětu 61
Porovnávání reálných čísel Co vypíše následující kód? double x; for (x = 0.0; x!= 1.0; x += 0.1) { printf("%f\n", x); } double x; for (x = 0.0; x < 1.0; x += 0.02) { printf("%f\n", x); } Martin Kačer, BI-EP2 1. Úvod do předmětu 62
Porovnávání reálných čísel PAMATUJTE: Desetinná čísla jsou nepřesná!!! double x; for (x = 0.0; x < 1.0; x += 0.1) { printf("%f\n", x); } 0.000000 0.100000 0.200000 0.300000 0.400000 0.500000 0.600000 0.700000 0.800000 0.900000 1.000000 Martin Kačer, BI-EP2 1. Úvod do předmětu 63
Porovnávání reálných čísel PAMATUJTE: Desetinná čísla jsou nepřesná!!! double x; for (x = 0.0; x <= 1.0; x += 0.02) { printf("%f\n", x); }... 0.860000 0.880000 0.900000 0.920000 0.940000 0.960000 0.980000 Martin Kačer, BI-EP2 1. Úvod do předmětu 64
Reálná čísla příklad Zjistěte, zda je bod [X,Y] uvnitř kruhu o poloměru R if (sqrt(x*x + y*y) <= r) Odmocnina je zbytečně pomalá a nepřesná if (x*x + y*y <= r*r) Lepší Funguje i pro celá čísla ale vlastně JEN pro celá čísla Martin Kačer, BI-EP2 1. Úvod do předmětu 65
Reálná čísla příklad if (x*x + y*y <= r*r) Nevhodné kvůli nepřesnostem reálných čísel Bod ležící na kružnici testem projít může a nemusí static final EPS = 1E-8; if (x*x + y*y < r*r + EPS) /* včetně kružnice */ if (x*x + y*y < r*r - EPS) /* vyjma kružnice */ Martin Kačer, BI-EP2 1. Úvod do předmětu 66
Magické epsilon Vždy používejte pro porovnávání! Pokud existuje rozdíl mezi < a <= Na úplnou rovnost if ( abs(a-b) < EPS ) Jak epsilon vybrat? Dostatečně velké, aby pomohlo Dostatečně malé, aby nevadilo o několik řádů menší než hodnoty Martin Kačer, BI-EP2 1. Úvod do předmětu 67
O chybách a tak
Typy chyb v úlohách Špatný algoritmus Neměl by se nám vůbec stávat (ale ) Chybná implementace Tady asi pomůže jen praxe (příp. review) Chyták Čtěte pořádně zadání a přemýšlejte! Martin Kačer, BI-EP2 1. Úvod do předmětu 69
Co dělat, když to nefunguje? Nesnažte se vzít větší kladivo Raději přemýšlejte! X Martin Kačer, BI-EP2 1. Úvod do předmětu 70
Runtime Error Kde k němu může dojít? Přístup do paměti Dělení Jiné výjimky (Java) Indexy a rozměry polí Dynamická alokace paměti Snažte se najít vstup, kde to spadne Martin Kačer, BI-EP2 1. Úvod do předmětu 71
Time Limit Exceeded Zkontrolujte čtení vstupu! Případná další nekonečná smyčka? Je váš algoritmus skutečně efektivní? Speciální případy: prázdný, největší Snažte se najít vstup, pro který je to podezřele pomalé Martin Kačer, BI-EP2 1. Úvod do předmětu 72
Wrong Answer Speciální případy prázdný jeden prvek Zkontrolujte znovu zadání Je váš algoritmus skutečně správný? Snažte se najít vstup, pro který to nefunguje (tady je to ale těžké) Martin Kačer, BI-EP2 1. Úvod do předmětu 73
Presentation Error Zkontrolujte texty Nevypisujete něco navíc? Ladící výstupy Formátování čísel (zejména reálných) Může znamenat i špatnou odpověď Případně mne kontaktujte Martin Kačer, BI-EP2 1. Úvod do předmětu 74
Stále nic? Přemýšlejte! Přečtete si znovu zadání, včetně detailů Ukažte to někomu jinému (pokud to jde) Napište to celé od začátku Nechte to být Martin Kačer, BI-EP2 1. Úvod do předmětu 75
To je pro dnešek vše Témata úloh pro další týden: Vybrané úlohy z EP1 Nepočítají se (přímo) do hodnocení ale zkuste si to! Martin Kačer, BI-EP2 1. Úvod do předmětu 76