Tehtävien deadline: su-ma yö 18.4. 1:59.
Viikon teemana on erityisesti syklit ja topologinen järjestäminen. Edellisen viikon aihe jatkuu osittain.
Saat syötteenä suunnatun verkon. Tehtävänäsi on selvittää, onko verkossa sykliä.
Toteuta seuraava metodi:
boolean onkoSyklia(int n, int[] mista, int[] minne)
Parametri n
on solmujen määrä,
kokonaisluku välillä 1..105.
Solmut on numeroitu 1..n
.
Taulukot mista
ja minne
kuvaavat kaaret solmujen välillä ja näitä kaaria on enintään 105. Kaaret ovat edelliseen viikkoon eroten yksisuuntaisia.
Metodin tulee palauttaa true
jos verkossa on sykli ja false
muuten.
# | metodin kutsu | haluttu palautusarvo |
---|---|---|
1 | onkoSyklia(3, new int[] {1, 2, 3}, new int[] {2, 3, 1}) | true |
2 | onkoSyklia(3, new int[] {1, 2}, new int[] {2, 3}) | false |
3 | onkoSyklia(3, new int[] {1, 2, 1}, new int[] {2, 3, 3}) | false |
4 | onkoSyklia(4, new int[] {2, 3, 4}, new int[] {3, 4, 2}) | true |
Saat syötteenä suunnatun asyklisen verkon, eli suunnatun verkon jossa ei ole syklejä. Tehtävänäsi on järjestää solmut topologisesti.
Toteuta seuraava metodi:
int[] jarjesta(int n, int[] mista, int[] minne)
Syöte kuvaa verkon samalla tavalla kuin tehtävässä 1. Myös syötteen rajat ovat samat.
Metodin tulee palauttaa luvut 1..n
jossain topologisessa järjestyksessä, eli jos solmusta i
pääsee solmuun j
, on luvun i
oltava ennen lukua j
palautetussa taulukossa.
Uolevi haluaa antaa lahjan jokaiselle ystävälleen. Uolevi ei halua antaa samaa lahjaa ystäville, jotka tuntevat toisensa, koska muuten lahja ei vaikuta henkilökohtaiselta. Toisaalta Uolevin varastossa on vain kahdenlaisia lahjoja: hän voi antaa joko kirjan tai karkkipussin. Onko Uolevin tavoite mahdollinen?
Oletetaan esimerkiksi, että Uolevin ystävät ovat A, B, C ja D. A tuntee kaikki muut ystävät, kun taas muut eivät tunne toisiaan. Nyt lahjojen jakaminen on mahdollista esimerkiksi niin, että A saa kirjan ja kaikki muut saavat karkkipussin.
Oletetaan sitten, että A ei tunne ketään, kun taas B, C ja D tuntevat kaikki toisensa. Nyt lahjojen jakaminen ei ole mahdollista, koska B:llä tulisi olla eri lahja kuin C:llä ja D:llä ja C:llä ja D:llä ei saa olla samaa lahjaa.
Toteuta seuraava metodi:
boolean lahjajako(int n, int[] mista, int[] minne)
Parametri n
on Uolevin ystävien määrä.
Se on kokonaisluku välillä 1..105.
Ystävät on numeroitu kokonaisluvuin 1..n
.
Taulukot mista
ja minne
kuvaavat ystävyyssuhteet.
Ystävyyssuhteiden määrä on 0..105. Voit olettaa, että ystävyyssuhteet ovat kaksisuuntaisia.
Metodin tulee palauttaa true
,
jos lahjojen jakaminen on mahdollista
Uolevin haluamalla tavalla, ja muuten false
.
# | metodin kutsu | haluttu palautusarvo |
---|---|---|
1 | lahjajako(4, new int[] {1, 2, 3}, new int[] {2, 3, 4}) | true |
2 | lahjajako(4, new int[] {1, 1, 1}, new int[] {2, 3, 4}) | true |
3 | lahjajako(3, new int[] {1, 2, 3}, new int[] {2, 3, 1}) | false |
4 | lahjajako(4, new int[] {1, 2, 3}, new int[] {2, 3, 1}) | false |
Saat syötteenä suunnatun verkon. Tehtävänäsi on laskea verkon vahvasti yhtenäisten komponenttien määrä.
Toteuta seuraava metodi:
int komponentteja(int n, int[] mista, int[] minne)
Solmujen määrä n
on kokonaisluku välillä 1..105 ja
solmut on numeroitu kokonaisluvuin 1..n
. Verkossa on korkeintaan 200000 kaarta.
# | metodin kutsu | haluttu palautusarvo |
---|---|---|
1 | komponentteja(3, new int[] {1,2,3}, new int[] {2,3,1}) | 1 |
2 | komponentteja(3, new int[] {1,1}, new int[] {2,3}) | 3 |
3 | komponentteja(3, new int[] {1,1,2}, new int[] {2,3,3}) | 3 |
4 | komponentteja(3, new int[] {1,1,2}, new int[] {2,3,1}) | 2 |
Uolevin seikkailupelissä on n
huonetta, joihin on piilotettu kolikoita. Huoneiden välillä pääsee liikkumaan ovia pitkin. Nämä ovet ovat siitä hieman outoja, että ne avautuvat vain yhteen suuntaan, joten yhdestä ovesta voi kulkea vain yhteen suuntaan. Lisäksi tiedetään, että huoneistossa ei ole sykliä.
Pelin hahmo aloittaa pelin huoneesta 1. Mikä on suurin mahdollinen määrä kolikoita, jonka pelin aikana voi saada? Uolevi saa päättää pelinsä missä tahansa huoneessa.
Toteuta seuraava metodi:
long kolikoita(int n, long[] k, int[] mista, int[] minne)
Parametri n
on kokonaisluku välillä 1..105.
Huoneet on numeroitu kokonaisluvuin 1..n
.
Taulukot mista
ja minne
kuvaavat huoneiden väliset ovet. Taulukon k
pituus on n+1
, luku k[i]
kertoo huoneessa i
olevien kolikoiden määrän. Tämä on kokonaisluku välillä 0..109.
Metodin tulee palauttaa suurin mahdollinen kolikoiden määrä, jonka pelin aikana voi kerätä.
# | metodin kutsu | haluttu palautusarvo |
---|---|---|
1 | kolikoita(3, new long[] {0, 1, 1, 1}, new int[] {1, 2}, new int[] {2, 3}) | 3 |
2 | kolikoita(3, new long[] {0, 1, 1, 1}, new int[] {2, 1}, new int[] {1, 3}) | 2 |
3 | kolikoita(4, new long[] {0, 1, 1, 1, 10}, new int[] {1, 2, 1}, new int[] {2, 3, 4}) | 11 |
4 | kolikoita(4, new long[] {0, 1, 1, 1, 1}, new int[] {1, 1, 1}, new int[] {2, 3, 4}) | 2 |