Obsah 3. přednášky: Metody - proč? Metoda - terminologie; návratová hodnota, parametry Popisy a volání metod Předávání parametrů Statické a lokální proměnné Přetěžování metod Ověřování funkce programu Tato tematika je zpracována v Záznamy přednášek: str. 64 - 66, 70 - 90 Poznámka: V této a v následující přednášce se můžete setkat s pojmy, které budou důkladně vysvětleny až později. Tyto „kolize“ jsou způsobeny odsunutím přednášky vysvětlující problematiku třídy tak, abyste získali co nejdříve znalosti potřebné pro zpracování semestrální práce.
Další úloha: Pomozte najít Nessy + 3 drobné úložky pro zájemce
Přednášky KIV/PPA1, A. Netrvalová, 2016
3. přednáška
Metody – proč? metoda = podprogram (forma sekvence příkazů realizující jednoduchý úkol) Java:
statické metody a metody instance (rozdílné užití bude vyloženo v přednášce o třídách a objektech) Příklady metod, se kterými jsme se již setkali: Math.max(num1, num2) System.out.println () main()
Metody obecně: - funkce (vrací hodnotu, např. Math.max(a,b)) - procedury (nevrací nic, např. tisk("Ahoj"))
Výhody (důvod) používání metod: -
dekompozice - snazší návrh přehlednost kódu neopakují se stejné sekvence kódu dobře se ladí (debugger) lépe se lokalizují chyby lépe se opravují
Nevýhoda - zvyšuje administrativu – nutno dodržet „formu“, tj. pravidla zápisu (deklarace neboli popis metody) a použití (volání metody) Strana 2 (celkem 28)
Metoda – terminologie; návratová hodnota, parametry Deklarace (popis) metody modifikátor hlavička metody
typ návratové hodnoty
název metody
parametry
public static int max(int num1, int num2) { int vysledek = 0;
(signatura)
if (num1 > num2) vysledek = num1; else vysledek = num2;
tělo metody
return vysledek; } }
návratová hodnota
Rozdělení metod dle typu a parametrů - bez parametrů a s parametry (1 a více, ale ne moc!) - nic nevrací, vrací hodnotu (kombinace – viz dále) Parametry metody (pokud je metoda má) jsou formální, za ně se při volání metody dosadí skutečné parametry. Metody v Javě nemohou být vnořené! Pohled uživatele:
Volitelná návratová hodnota
Volitelný vstup
Signatura metody Tělo metody
Black Box Strana 3 (celkem 28)
Popisy (deklarace) a volání metod (jméno + parametry) import java.util.*; public class VolaniMetod { public static int vetsi(int prvni, int druhe) { if(prvni>druhe) { // formalni parametry return prvni; } else { return druhe; } } public static int vratNahodneCislo(){ Random r = new Random(); return r. nextInt(10); } public static void vypisCeleCislo(int cislo){ System.out.println(cislo); } public static void vypisMail (){ // malokdy System.out.println("mail:
[email protected]"); }
}
P O P I S Y M E T O D
public static void main(String []args) { V int a = -5, b = -6; O int vetsi = vetsi(a,b); // skutecne parametry L int nahodne = vratNahodneCislo(); Á vypisCeleCislo(vetsi); N vypisCeleCislo(nahodne); -5 Í vypisMail(); 9 } mail:
[email protected] Strana 4 (celkem 28)
Při volání metody se řízení programu předá volané metodě, po jejím skončení se pokračuje v místě, odkud byla metoda volána.
Typy volání: - metoda může volat (v těle nebo v parametru) jinou metodu - metoda může volat sama sebe (rekurze) - zanořené volání Př.: System.out.println(vetsi(vratNahodneCislo(),5)); (méně přehledné, hůře laditelné)
Předávání parametrů (volající volaná) - parametry primitivních typů se předávají hodnotou (parametr je jen vstupní! - viz příklad dále) - parametrem může být i výraz - způsob předání je dán, nelze volit ani ovlivnit
Postup předání parametru a další výpočet je-li parametrem výraz, vypočte se jeho hodnota hodnota se uloží do zásobníku (datová struktura) je-li parametrem proměnná, uloží se její kopie vyvolaná metoda „přečte“ uloženou hodnotu můžeme ji výpočtem metodě měnit, ale výsledek se vně volané metody neprojeví (důvodem je volání hodnotou) - pokud ji i nadále potřebujeme, je nutno její hodnotu vrátit (viz dále)
-
Strana 5 (celkem 28)
public class VolaniHodnotou { /** Metoda prohozeni hodnot dvou promennych */
public static void prohod(int n1, int n2) { System.out.println("Metoda prohod"); System.out.println(" pred: n1 = " + n1 + ", n2 = " + n2); // prohozeni n1 a n2
int temp = n1; n1 = n2; n2 = temp; System.out.println(" po: n1 = " + n1 + ", n2 = " + n2); } /** Metoda main() */
public static void main(String[] args) { // Deklarace a inicializace promennych
int num1 = 1; int num2 = 2; System.out.println("Inicializace:"); System.out.println("num1 = " + num1 + ", num2 = " + num2); // volani metody prohod()
prohod(num1, num2); System.out.println("Po navratu do main():"); System.out.println("num1 = " +num1 + ", num2 = " + num2); } }
Inicializace: num1 = 1, num2 = 2 Metoda prohod pred: n1 = 1, n2 = 2 po: n1 = 2, n2 = 1 Po navratu do main(): num1 = 1, num2 = 2 Strana 6 (celkem 28)
public class ZmenaHodnotyParametru { public static void zmenParametr(int cislo) { cislo++; System.out.println("zmenParametr: cislo = " + cislo); } public static void main(String []args) { int index = 0; System.out.println("main(): index = " + index); zmenParametr(index); System.out.println("main(): index = " + index); } }
main(): index = 0 zmenParametr: cislo = 1 main(): index = 0
Možná úprava (úmyslná, potřebujeme hodnotu cislo): public class ZmenaHodnotyParametruTrvala { public static int zmenParametr(int cislo) { cislo++; System.out.println("zmenParametr: cislo = " + cislo); return cislo; }
}
public static void main(String []args) { int index = 0; System.out.println("main(): index = " + index); int indexNovy = zmenParametr(index); System.out.println("main(): indexNovy = " + indexNovy); } main(): index = 0 zmenParametr: cislo = 1 main(): novy index = 1 Strana 7 (celkem 28)
Příklad: Napište program pro výpočet vzdálenosti dvou bodů v rovině, bez a s použitím metod.
v
x1 x2 2 y1 y2 2
import java.util.*;
// Bez pouziti metod
public class VzdalenostDvouBoduVRovine { private static Scanner sc = new Scanner(System.in); public static void main(String [] args){ sc.useLocale(Locale.US); // lokalizace double x1 = sc.nextDouble(); double y1 = sc.nextDouble(); double x2 = sc.nextDouble(); double y2 = sc.nextDouble(); System.out.println("x1=" + x1 +", y1=" + y1) ; System.out.println("x2=" + x2 +", y2=" + y2) ; double v = Math.sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)); System.out.println("v = " + v); } }
x1=0.0, y1=0.0 x2=1.0, y2=1.0 v = 1.4142135623730951 Strana 8 (celkem 28)
import java.util.*; // S pouzitim metod public class VzdalenostDvouBoduVRovine { private static Scanner sc = new Scanner(System.in); private static Formatter f = new Formatter(System.out, Locale.US); static double nactiHodnotu(){ // nacte a vrati hodnotu System.out.print("Nacti souradnici: "); sc.useLocale(Locale.US); // lokalizace return sc.nextDouble(); } static double spoctiVzdalenost(double x1, double y1, double x2, double y2){ double dX = x1 - x2; double dY = y1 - y2; return Math.sqrt(dX*dX + dY*dY); // vrati spoctenou vzdalenost } static void vypis(double hodnota){ f.format("vzdalenost = %g%n", hodnota); // formatovany vystup f.close(); // uzavre Formatter } public static void main(String [] args){ // volani metod double x1 = nactiHodnotu(); double y1 = nactiHodnotu(); double x2 = nactiHodnotu(); double y2 = nactiHodnotu(); double v = spoctiVzdalenost(x1,y1,x2,y2); vypis(v); Nacti souradnici: -10.5 } }
Nacti souradnici: -10.5 Nacti souradnici: 10.5 Nacti souradnici: 10.5 vzdalenost = 29.6985 Strana 9 (celkem 28)
Příklad: Jsou-li zadané strany a, b, c rozhodněte, zda tvoří trojúhelník a pokud ano rozhodněte, zda je ostroúhlý, pravoúhlý či tupoúhlý. import java.util.*; public class TypyTrojuhelniku { static private Scanner sc = new Scanner(System.in); static String jakyTrojuhelnik(int a, int b, int c){ if(a*a+b*b>c*c){ return "Trojuhelnik je ostrouhly."; } else{ if(a*a+b*b
c && a+c>b && b+c>a){ System.out.println(jakyTrojuhelnik(a,b,c)); } else { System.out.println("Netvori trojuhelnik!"); } / / mozno pridat do metody } } // vsimnete si ladeni programu – pruchod vsemi vetvemi! Strana 10 (celkem 28)
Příklad
(viz minulá přednáška, program v metodě main())
Otestujte, zda zadané strany tvoří trojúhelník. Pokud tvoří, vypočtěte jeho obsah. Napište statické metody: double nactiStranu() boolean otestuj(double a, double b, double c) double spoctiObsah(double a, double b, double c)
import java.util.*; public class Trojuhelnik { static private Scanner sc = new Scanner(System.in); public static double nactiStranu(){ sc.useLocale(Locale.US); System.out.print("Zadej stranu: "); return sc.nextDouble(); } public static boolean otestuj (double a, double b, double c) { if ((a+b)>c && (b+c)>a && (a+c)>b){ return true; } else { return false; } } public static double spoctiObsah(double a, double b, double c) {
double s=(a+b+c)/2; return Math.sqrt(s*(s-a)*(s-b)*(s-c)); } pokračování na dalším slajdu ... Strana 11 (celkem 28)
public static void main(String[] args) { double a = nactiStranu(); double b = nactiStranu(); double c = nactiStranu(); if (otestuj (a,b,c)){ System.out.println("O = " + spoctiObsah(a,b,c)); } else { System.out.println("Strany netvori trojuhelnik!"); } Zadej stranu: 3 } Zadej stranu: 4 } Zadej stranu: 5 O = 6.0 Zadej stranu: 1 Zadej stranu: 2 Zadej stranu: 3 Strany netvori trojuhelnik!
Příklad – problém* Z konečné stanice vyjedou současně autobusy na několik linek, z nichž každá má zadaný interval odjezdů (v minutách). Určete počet minut, po jejichž uplynutí opět vyjedou všechny tyto linky společně. Hledáme nejmenší společný násobek Např. 4 linky s intervaly 15, 20, 45, 25 minut 15 = 3 . 5 20 = 2 . 2 . 5 45 = 3 . 3 . 5 25 = 5 . 5 ( 15; 20; 45; 25 ) = 2 . 2 . 3 . 3 . 5 . 5 = 900 Strana 12 (celkem 28)
import java.util.*; public class AutobusoveLinky { static private Scanner sc = new Scanner(System.in); static int najdiNSN (int prvni, int druhe) { int p = prvni; // ulozeni cisel do pom promennych p a d int d = druhe; if (p != d){ // nejsou stejna Zadej pocet linek: 4 Zadejte interval linky: 15 int zbytek; Zadejte interval linky: 20 if ( p > d ){ Zadejte interval linky: 45 zbytek = p % d; Zadejte interval linky: 25 } else zbytek = p; Pocet minut = 900 while (zbytek != 0) { p = d; // do prvniho dej druhe d = zbytek; // do druheho dej zbytek zbytek = p % d; // nastav novy zbytek } // NSN: soucin cisel deleny poslednim nenulovym zbytkem p = prvni*druhe/d; } return p; // vrat NSN } public static void main(String[] args) { System.out.print("Zadej pocet linek: "); int pocetLinek = sc.nextInt(); System.out.print("Zadejte interval linky: "); int interval = sc.nextInt(); for(int i=1; i<pocetLinek; i++) { System.out.print("Zadejte interval linky: "); int interval2 = sc.nextInt(); interval = najdiNSN (interval, interval2); } System.out.println("Pocet minut = " + interval); } } Strana 13 (celkem 28)
Statické a lokální proměnné - rozdělení proměnných: dle místa deklarace
Lokální proměnné - deklarované v metodě - použitelné pouze v této metodě (bloku), obdobně jako to bylo u proměnné v cyklu for - při použití ve volané metodě nutno předat jako skutečný parametr
Statické proměnné – deklarované v třídě mimo metody, obvykle hned za hlavičkou třídy - při deklaraci nutný modifikátor static - použitelné ve všech metodách (výhoda i nevýhoda) - zvýšená možnost obtížně odhalitelné chyby, proměnná se někde se změnila, kde? - používat omezeně, v oprávněných případech
Jak je používat? - významové pojmenování - deklarace na samostatném řádku - provedena inicializace (metodou, v main()) public class Nastaveni { static int cislo = 0; static private Random r; public static void main(String [] args){ r = new Random(); cislo = r.nextInt(); } } Strana 14 (celkem 28)
Zastínění statické proměnné lokální proměnnou - paměť pro statickou proměnnou přidělena na začátku programu, je k dispozici do konce programu
- paměť pro lokální proměnnou přidělena při vstupu do metody, k dispozici je do konce metody public class ZastineniPromenne { static int promenna = 2; //staticka promenna static void zastin(){ int promenna =7; // promenna metody zastin() System.out.println ("promenna metody: " + promenna); } public static void main(String [] args){ System.out.println("promenna staticka: " + promenna); zastin(); int promenna = 5; // promenna metody main() // staticka je uz od ted nedostupna
System.out.println("promenna v main: " + promenna); } }
promenna staticka: 2 promenna metody: 7 promenna v main: 5
Přetěžování metod (overloading) přetížená metoda = metoda se stejným jménem, která se liší parametry
- počtem - typem - pořadím (nevhodné)
Tyto metody bývají funkčně podobné, provádějí stejnou činnost, ale s různými datovými typy či s upřesněním Strana 15 (celkem 28)
public class PretizeneMetody { /** nalezeni nejvetsi ze dvou celociselnych hodnot */
static int max(int num1, int num2){ if (num1 > num2) return num1; else return num2; } /** nalezeni nejvetsi ze dvou realnych hodnot */
static double max(double num1, double num2){ if (num1 > num2) return num1; else return num2; } /** nalezeni nejvetsi ze tri celych hodnot */
static int max(int num1, int num2, int num3){ return max(max(num1, num2), num3); } public static void main(String[] args){ // volani metody se dvema int parametry
System.out.println("parametry: 3 a 4 = " + max(3, 4)); // volani metody se dvema double parametry
System.out.println("parametry: 5.5 a 5.4 = " + max(5.5, 5.4)); // volani metody se tremi int parametry
System.out.println("parametry: 3, 5 a 10 = " + max(3, 5, 10)); } }
parametry: 3 a 4 = 4 parametry: 5.5 a 5.4 = 5.5 parametry: 3, 5 a 10 = 10 Strana 16 (celkem 28)
Příklad: Napište program Auto.java, s proměnnými kapacita a obsah nádrže a spotřeba. Realizujte metody o void natankuj(int pocetLitru) o void natankuj() - plnou nádrž o double kolikUjede() - s daným obsahem o void ujelo(double vzdalenost) - vypočte obsah nádrže po ujetí dané vzdálenosti a ověřte funkčnost programu. public class Auto { // statické promenne a konstanty static final double KAPACITA_NADRZE = 45; static double obsahNadrze = 0; static double spotreba = 8; // natankuj cast nadrze PRETIZENE METOTY static void natankuj(int pocetLitru) { double doplneni = obsahNadrze + pocetLitru; obsahNadrze = doplneni>KAPACITA_NADRZE ? KAPACITA_NADRZE : doplneni; } // natankuj plnou nadrz static void natankuj(){ obsahNadrze = KAPACITA_NADRZE; } //vypocte dojezd s momentalnim obsahem nadrze static double kolikUjede() { return obsahNadrze / spotreba * 100; } // spocte obsah nadrze po ujeti zadane vzdalenosti static void ujelo(double vzdalenost) { obsahNadrze -= vzdalenost / 100 * spotreba; } Strana 17 (celkem 28)
public static void main(String[] args) { System.out.println("Kapacita nadrze: "+ KAPACITA_NADRZE + " l"); System.out.println("Spotreba: "+ spotreba + " l/100km"); System.out.println("Obsah nadrze: " + obsahNadrze + " l\n"); natankuj(); // plnou System.out.println("Obsah nadrze: "+ obsahNadrze +" l"); int vzdalenost = 500; ujelo(vzdalenost); // ujelo 500 km System.out.println("Ujelo vzdalenost: " + vzdalenost +" km"); System.out.println("Obsah nadrze: " + obsahNadrze + " l\n"); spotreba = 9; // zvetseni spotřeby System.out.println("Spotreba: "+ spotreba+" l/100km"); System.out.println("Maximalni dojezd: "+ (int)kolikUjede() +" km\n"); natankuj(30); // dotankuj System.out.println("Obsah nadrze: " + obsahNadrze + " l"); System.out.println("Maximalni dojezd: "+ (int)kolikUjede() +" km");
Kapacita nadrze: 45.0 l Spotreba: 8.0 l/100km Obsah nadrze: 0.0 l Obsah nadrze: 45.0 l Ujelo vzdalenost: 500 km Obsah nadrze: 5.0 l Spotreba: 9.0 l/100km Maximalni dojezd: 55 km Obsah nadrze: 35.0 l Maximalni dojezd: 388 km
Strana 18 (celkem 28)
Příklad: Napište program, který spočte vzdálenost k místu úderu blesku, je-li hrom slyšet po zadané době v [s], jinak rozhodne, zda bouřka skončila (není blesk), či je bouřka už moc daleko (není hrom). Logické hodnoty reprezentující skutečnost, zda blesk či hrom nastal, vygenerujte náhodně. public class Bourka { private static Scanner sc = new Scanner(System.in); private static Random r = new Random(); static final double RYCHLOST_ZVUKU = 0.335; // v km/s static double nactiDobu(){ sc.useLocale(Locale.US); System.out.print("Zadej dobu: "); double time = sc.nextDouble(); return time; } static double spoctiVzdalenost(double time){ return time * RYCHLOST_ZVUKU; } static boolean generuj(){ // blesk, hrom return r.nextBoolean(); } static void vypis(String text){ PRETIZENE METOTY System.out.println(text); } static void vypis(double d){ System.out.println(d); } static void vypis(String text, boolean b){ System.out.println(text + b); } Strana 19 (celkem 28)
static void udelejBourku(){ boolean blesk=true, hrom = true; // poc. hodnoty vypis("Bourka zacala."); vypis("Blesk: ", blesk); vypis("Hrom: ", hrom); while(blesk){ if(hrom){ double dist = spoctiVzdalenost(nactiDobu()); vypis("Blesk byl ve vzdalenosti [km]: ", dist); } else{ vypis("Bourka je moc daleko."); } blesk = generuj(); hrom = generuj(); if(!blesk){ vypis("Blesk: ", blesk); vypis("Hrom: ", false); vypis("Bourka skoncila."); break; } vypis("Blesk: ", blesk); vypis("Hrom: ", hrom); } } public static void main(String args[]) { udelejBourku(); } } Strana 20 (celkem 28)
Bourka zacala. Blesk: true Hrom: true Zadej dobu: 1.2 Blesk byl ve vzdalenosti: 0.402 Blesk: true Hrom: false Bourka je moc daleko. Blesk: false Hrom: false Bourka skoncila. Bourka zacala. Blesk: true Hrom: true Zadej dobu: 1.2 Blesk byl ve vzdalenosti: 0.402 Blesk: true Hrom: false Bourka je moc daleko. Blesk: true Hrom: false Bourka je moc daleko. Blesk: true Hrom: true Zadej dobu: 2.5 Blesk byl ve vzdalenosti: 0.8375 Blesk: true Hrom: false Bourka je moc daleko. Blesk: true Hrom: true Zadej dobu: 3 Blesk byl ve vzdalenosti: 1.005 Blesk: false Hrom: false Bourka skoncila. Strana 21 (celkem 28)
Příklad: Zkontrolujte zadání PIN kódu do mobilu. Je-li správné, vypište text „PIN je ok!“ a program ukončete, jinak vypište text „PIN není ok!“. Přesáhl-li počet pokusů maximálně dovolený počet, vypište rovněž text „SIM byla zablokována!“. import java.util.*; public class KontrolaNacteniPin { private static Scanner sc = new Scanner(System.in); static final int PIN = 1234; static final int MAX_POCET_POKUSU = 3; static boolean kontrolaPin(int pin){ if(pin != PIN){ return false; } return true; } public static void main(String[] args) { for(int pZad=1; pZad<= MAX_POCET_POKUSU; pZad++) { System.out.print("Zadej 4-mistny PIN: "); Zadej 4-mistny PIN: int pin = sc.nextInt(); 1235 if(kontrolaPin(pin)){ PIN neni OK! Zadej 4-mistny PIN: System.out.println("PIN je OK!"); 1236 System.exit(0); PIN neni OK! } Zadej 4-mistny PIN: 1237 else { PIN neni OK! System.out.println("PIN neni OK!"); SIM je zablokovana! } } 4-mistny PIN: System.out.println("SIM byla zablokovana!"); Zadej 1235 } PIN neni OK! Zadej 4-mistny PIN: } 1234 PIN je OK! Strana 22 (celkem 28)
Ověřování funkce programu Přehledný zápis zdrojového kódu (odsazení textu, bloky, řádkování, názvy, …)! Programy je nutno ladit! 1. Syntaxe – ověřit překladem Není-li přeložen bez chyb - odstranit vypsané chyby (postupně) - překládat, do odstranění poslední chyby 2. Úspěšný překlad, ale funguje program správně? - ověřit na testovacích datech - ověřit na dalších „vhodně“ zvolených datech Ilustrační triviální příklad:
public class SoucetNPrvnichCisel { public static void main(String[] args) { int n = 1; // pro n=0: s=0, s(n)=0 OK! int s = 0; for (int i=1; i==n; i++) { // chyba - ma byt: <= s = s + i; System.out.println("i = " + i + ": s = " + s); } System.out.println("s = " + s); System.out.println("s(n) = " + (n+1)*n/2); } }
Pro n = 5: s=0, ale s(n)=15 ???
i = 1: s = 1 s = 1 s(n) = 1 Strana 23 (celkem 28)
Příkaz Assert - umožní kontrolu hodnot při spuštění s volbou -ea import java.util.*; public class Assert { // použijte -ea v příkazu java
private static Scanner input = new Scanner( System.in ); public static void main( String args[] ) { System.out.print( "Zadejte cislo mezi 0 and 10: " ); int cislo = input.nextInt(); // tvrdime ze cislo musi byt >= 0 a <= 10
assert ( cislo >= 0 && cislo <= 10 ) : "Chybne cislo: " + cislo; System.out.printf( "Zadali jste %d\n", cislo ); } }
Více o ladění programů: na 7. přednášce Strana 24 (celkem 28)
… a ještě jedna úloha k promyšlení
Pátrání po Nessy Lochnesská příšera je bájné zvíře údajně žijící ve velkém a hlubokém jezeře Loch Ness poblíž města Inverness v severním Skotsku. Toto tajemné zvíře můžeme v literatuře často najít pod přezdívkou Nessy.
Téměř před deseti lety, v červenci 2003, BBC ohlásila rozsáhlé pátrání v jezeře Loch Ness, které provedl její tým odborníků. K pátrání bylo použito 600 různých měření sonarem, avšak v jezeře Loch Ness nebyly nalezeny žádné stopy vodní příšery (tj. velkého vodního zvířete, ať už známého nebo neznámého). BBC tehdy došla k závěru, že žádná Nessy neexistuje. Nyní se uvažuje o opakování experimentu. Pomůžete hledat Nessy? Je dána obdélníková oblast o n řádcích a m sloupcích, která představuje jezero Loch Ness. Pro její rozměry platí 6 ≤ (m, n) ≤ 10000. Naším úkolem je najít minimální počet sonarů, které Strana 25 (celkem 28)
musíme umístit na určitá políčka mřížky tak, abychom měli pod kontrolou celou oblast. Je nutno dodržet následující podmínky: Na jednom políčku může být umístěn pouze jeden sonar a ten umožňuje hlídat toto políčko a všechna políčka k němu přilehlá. Políčka při okrajích mapy není nutno hlídat, protože je jasné, že se Nessy nemůže schovat v mělké vodě na okrajích jezera. Příklad oblasti s jedním sonarem, kde znak x reprezentuje sonar a šedě vybarvená políčka jsou místa, která jsou monitorována tímto sonarem, je znázorněn na Obr.1 Příklad s více sonary, tj. jedno z možných řešení rozmístění sonarů pro obdélník s rozměry 9 x 13, je ukázán na Obr.2.
Obr. 1
Obr. 2 Strana 26 (celkem 28)
Vstup Na první řádce vstupu se nachází celé číslo t (t ≤ 100) určující počet testovaných případů. Každý testovaný případ se nachází na jedné další řádce, která se skládá ze dvou celých čísel m a n oddělených navzájem mezerou. Tato čísla reprezentují počet řádek a počet sloupců prohledávané oblasti. Výstup Pro každý testovaný případ vypište na novou řádku nejmenší počet sonarů potřebných k monitorování oblasti celého jezera. Příklad vstupu 3 66 77 9 13 Příklad výstupu 4 4 12
Řešení je možno i odevzdat na validátor
ACM – číslo úlohy 11044 Strana 27 (celkem 28)
Úložky pro zájemce (řešení mailem – předmět: triUlozky, co nejdříve po přednášce)
1. BUBLIK V následující rovnici nahraďte každé písmeno číslicí (různým písmenům odpovídají odlišné číslice) LIK * LIK = BUBLIK Nalezněte řešení - napište program, popř. proveďte matematický výpočet.
2. Číslice s nejčastějším výskytem Jsou dána čísla 1, 2, …, 1000000. Pak každé číslo nahradíme součtem jeho cifer. Tuto operaci opakujeme, dokud všechna čísla nejsou jednociferná. Jaká je číslice s nejčastějším výskytem – napište program (výsledek ověřte i matematickým výpočtem).
3. Počet částic V určitém bodě na přímce se nachází částice. Po uplynutí vteřiny se rozpadne na dvě částice, které se rozejdou opačnými směry a zastaví se ve vzdálenosti 1 od původní polohy. Za další vteřinu každá z nových částic znovu dělí na dvě částice, které se opět rozejdou a zastaví ve vzdálenosti + od původních poloh. Když se setkají dvě částice, tak dojde k jejich zániku. Například, po dvou vteřinách zůstanou pouze dvě částice. Kolik částic zbyde po 129 vteřinách? A kolik jich bude obecně po N vteřinách? Napište program (výsledek ověřte i matematickým výpočtem). Strana 28 (celkem 28)