Tehtävien deadline: ma 30.3. klo 01:59
Näissä tehtävissä sovelletaan syvyys- ja leveyssuuntaista hakua.
Tee metodi
boolean tietoverkko(boolean[][] verkko)
,
jolle annetaan kuvaus tietoverkosta ja joka tarkistaa, pystyvätkö
kaikki verkon koneet viestimään keskenään. Toisin sanoen ohjelman
tulee tarkistaa, onko verkko yhtenäinen.
Verkossa on n konetta, jotka on numeroitu kokonaisluvuin 0...n-1. Voit olettaa, että n on korkeintaan 1000.
Verkon kuvaus on
vierusmatriisi,
eli kaksiulotteinen
taulukko
verkko
,
jossa
verkko[i][j]
on
true
jos koneitten
i
ja
j
välillä menee yhteys.
Tämän verkon vierusmatriisi:
3 /|\ 4 | 0 \|/ \ 1---2
on:
01110 10111 11000 11001 01010
ja verkko on yhtenäinen.
Tämän verkon vierusmatriisi:
3 /| 4 | 0 \| | 1 2
on:
00100 00011 10000 01001 01010
ja verkko ei ole yhtenäinen.
Saat talon pohjapiirustuksen. Tehtävänäsi on laskea, montako huonetta talossa on. Huone tarkoittaa yhtenäistä seinien rajaamaa lattiatilaa.
Toteuta metodi
int huoneet(char[][] talo)
,
joka
palauttaa huoneitten lukumäärän. Pohjapiirroksessa
merkki
'#'
tarkoittaa seinää ja merkki
'.'
lattiaa.
Huom: juuri kartan reunojen ulkopuolella on (implisiittiset) seinät. Siis esimerkiksi seuraavassa kartassa on kaksi huonetta:
. # .
########## #.###....# #..#####.# #...#.##.# ##########
Huoneita: 3
########## #.#...##.# #.#.#....# #.....##.# ##########
Huoneita: 1
Tällä kertaa huoneitten laskemisen sijaan on tehtävänä laskea
huoneitten koot. Toteuta metodi
ArrayList<Integer>
koot(char[][] talo)
joka palauttaa huoneitten koot (jossain
järjestyksessä) ArrayListissä.
Talon pohjapiirros annetaan ohjelmalle samassa muodossa kuin edellisessä tehtävässä.
Pohjapiirros:
########## #.###....# #..#####.# #...#.##.# ##########
Huoneiden koot: 6,6,1
Tässä talossa on kaksi huonetta, joiden koko on 6 ruutua, ja yksi huone, jonka koko on 1 ruutu.
Pohjapiirros:
########## #.#..#.#.# ######.### #..#.#.#.# ##########
Huoneiden koot: 3,2,2,1,1,1,1
Ratsu liikkuu shakkilaudalla kulkemalla kaksi ruutua johonkin
suuntaan (vasen, oikea, ylös alas), ja sitten yhden ruudun edellisen
suunnan kanssa suorassa kulmassa olevaan suuntaan. Seuraavassa on
piirretty ratsun (R
) kaikki mahdolliset seuraavat
ruudut (x
):
........ ........ ..x.x... .x...x.. ...R.... .x...x.. ..x.x... ........
Tehtävänäsi on etsiä ratsun lyhin reitti annetusta 8x8
shakkilaudan ruudusta toiseen. Toteuta metodi
int ratsu(int
x0, int y0, int x1, int y1)
,
joka palauttaa lyhimmän reitin
pituuden lähtöruudusta
(x0,y0)
maaliruutuun
(x1,y1)
.
ratsu(0,0,1,2)=1
0....... ........ .1...... ........ ........ ........ ........ ........
ratsu(0,0,7,7)=6
(samanpituisia reittejä on toki useita)
0....... ........ .1...... ...2.... .....3.. .......4 .....5.. .......6
HUOMAUTUS! Ennen tämän tehtävän tekemistä kannattaa tutustua Floyd-Warshallin algoritmiin. Vaikka se tuleekin myöhemmin kurssilla painotettujen verkkojen yhteydessä, tarjoaa se kätevän tavan laskea tarpeeksi pienien verkkojen lyhimmät etäisyydet kaikille verkon solmupareille. Tämän tehtävän toteutus leveyshaulla on huomattavasti ikävämpää kuin käyttäen Floyd-Warshallia. Voit lukea algoritmista esimerkiksi kisakoodarin käsikirjan luvusta 17.
Uolevi on kokenut lentomatkaaja ja kertoo usein tarinoita matkoistaan. Mutta Maijan mielestä jotkin Uolevin tarinat kuulostavat epäilyttäviltä.
Tehtäväsi on selvittää, mitkä Uolevin tarinoista voivat pitää paikkansa ja mitkä ovat varmasti valetta.Oletetaan esimerkiksi, että lentoasemia on 4 ja lentoyhteyksiä on 2: asemalta 1 pystyy lentämään asemille 2 ja 3. Uolevi väittää:
Väite 1 voi olla totta, koska asemalta 1 on lentoyhteys asemalle 2. Väite 2 voi myös olla totta, koska Uolevi on voinut lentää 1->2->1->2->1 käyttäen 4 lentoa. Väite 3 on valetta, koska asemalle 2 voi päästä 1 tai 3 lennolla mutta ei 2 lennolla. Väite 4 on valetta, koska asemalle 4 ei pääse mitenkään, erityisesti ei 3 lentoa käyttäen.
Tehtäväsi on toteuttaa luokka Lentoreitit
, joka tarjoaa seuraavat metodit:
Lentoreitit(int n, int[] mista, int[] minne)
:boolean mahdollinen(int alku, int loppu, int lennot)
:alku
ja saavuin lennot
lennon jälkeen paikkaan loppu
"
Lentoasemien määrä n
on välillä 1..100,
ja asemat on numeroitu kokonaisluvuin 1..n
.
Lentoyhteyksien määrä on välillä 1..105.
Kaikki yhteydet ovat kaksisuuntaisia.
Uolevin väitteitä on välillä 1..105,
ja jokaisessa väitteessä alku
ja loppu
ovat lentoasemien numerot ja
lennot
on kokonaisluku välillä 1..109.
Jos väite voi olla totta, metodin tulee palauttaa true
,
ja jos väite on varmasti valetta,
metodin tulee palauttaa false
.
Seuraava koodi testaa luokkaa:
Lentoreitit x = new Lentoreitit(4, new int[] {1, 1}, new int[] {2, 3}); System.out.println(x.mahdollinen(1, 2, 1)); System.out.println(x.mahdollinen(1, 1, 4)); System.out.println(x.mahdollinen(1, 2, 2)); System.out.println(x.mahdollinen(1, 4, 3));
Koodin tulostuksen tulisi olla seuraava:
true true false false