Viikko 12: TMC-tehtävät

TMC viikko 12

Tehtävien deadline: su-ma yö 2.5. 1:59.

Viikon aiheena on pienimmät virittävät puut ja union find.


Tehtävä 1

Tehtäväsi on pitää kirjaa tieverkoston rakenteesta, kun kaupunkien välille rakennetaan teitä.

Toteutus

Toteuta luokka Tiet, joka tarjoaa seuraavat metodit:

Testauksessa metodeita kutsutaan enintään noin 300000 kertaa.

Esimerkki

Seuraava koodinpätkä testaa luokan toimintaa:

Tiet t=new Tiet(5);
System.out.println(t.yhteys(1,2));
System.out.println(t.yhteys(1,1));
t.rakenna(1, 2);
System.out.println(t.yhteys(1,2));
System.out.println(t.yhteys(1,3));
t.rakenna(2, 3);
System.out.println(t.yhteys(1,3));
t.rakenna(1, 4);
System.out.println(t.yhteys(4,3));

Tulosteen tulisi näyttää tältä:

false
true
true
false
true
true

Tehtävä 2

Tieverkosto on päässyt huonoon kuntoon, ja se tulisi kunnostaa. Rahaa on kuitenkin vähän, eikä kaikkia teitä voi korjata. Tehtäväsi on etsiä sellainen joukko teitä, että minkä tahansa kahden kaupungin välillä pystyy kulkemaan vain korjattuja teitä ja kokonaiskustannus on mahdollisimman alhainen.

Toteutus

Toteuta seuraava metodi:

long kunnostus(int n, int[] mista, int[] minne, int[] hinta)

Parametri n on kaupunkien määrä, kokonaisluku välillä 1..105. Kaupungit on numeroitu tuttuun tapaan kokonaisluvuin 1..n.

Taulukot mista, minne ja hinta kuvaavat tieverkoston tiet. Taulukko mista kertoo, mistä kaupungista tie alkaa, ja taulukko minne kertoo, mihin kaupunkiin tie päättyy. Kaikki tiet ovat kaksisuuntaisia, ja niiden määrä on välillä 0..105. Lisäksi taulukko hinta kertoo, paljonko tien kunnostaminen maksaisi. Jokainen hinta on kokonaisluku välillä 1..109.

Metodin tulee palauttaa pienin kokonaiskustannus, jolla teitä saadaan korjattua siinä määrin, että minkä tahansa kaupunkiparin välillä pääsee kulkemaan korjattujen teiden kautta.

Esimerkit

#metodin kutsuhaluttu palautusarvo
1kunnostus(3, new int[] {1, 2}, new int[] {2, 3}, new int[] {7, 4})11
2kunnostus(3, new int[] {1, 2, 1}, new int[] {2, 3, 3}, new int[] {7, 4, 5})9
3kunnostus(3, new int[] {1, 2, 1}, new int[] {2, 3, 3}, new int[] {2, 2, 2})4

Tehtävä 3

Sinulle on annettu tiedot rautatieverkostosta, joka muodostuu kaupungeista ja niiden välisistä radoista. Jokaisesta rataosuudesta tiedetään myös, mikä on maksimipaino siinä ajavalle junalle. Jokaista rataosuutta voidaan tarvittaessa vahvistaa mielivaltaisen paljon. Kuinka montaa rataosuutta joudut vahvistamaan, jotta juna, jonka paino on W, pystyisi matkustamaan minkä tahansa kaupunkiparin välillä?

Toteutus

Toteuta seuraava metodi:

int vahvistuksia(int n, int[] mista, int[] minne, int[] raja, int W)

Parametri n on kaupunkien määrä, kokonaisluku välillä 1..105. Kaupungit on numeroitu tavalliseen tapaan kokonaisluvuin 1..n.

Taulukot mista ja minne kuvaavat yhteydet kaupunkien välillä. Taulukko raja kertoo jokaisesta yhteydestä junan maksimipainon. Yhteyksien määrä on välillä 0..105.

Metodin tulee palauttaa pienin mahdollinen määrä vahvistuksia, jolla W -painoinen juna voi matkustaa minkä tahansa kaupunkiparin välillä. Rautatieverkosto on aina yhtenäinen.

Esimerkit

#metodin kutsuhaluttu palautusarvo
1vahvistuksia(2, new int[]{1}, new int[]{2}, new int[]{9}, 10)1
2vahvistuksia(3, new int[]{1,2}, new int[]{2,3}, new int[]{9,1}, 10)2
3vahvistuksia(3, new int[]{1,2,1}, new int[]{2,3,3}, new int[]{9,1,10}, 10)1
4vahvistuksia(4, new int[]{1,1,2,3}, new int[]{2,3,3,4}, new int[]{10,9,9,8}, 10)2

Tehtävä 4

Tehtävänäsi on selvittää, moneenko eri komponenttiin kaupunkiverkosto jakautuu, kun teitä suljetaan.

Toteutus

Tehtävänäsi on toteuttaa seuraava metodi:

int[] komponentteja(int n, int[] mista, int[] minne, int[] poistot)

Parametrit n, mista ja minne kuvaavat kaupungit ja kaupunkien väliset kaksisuuntaiset tiet kuten aiemmissa tehtävissä. Teiden lukumäärä m on korkeintaan 105.

Taulukko poistot kertoo, missä järjestyksessä teitä suljetaan. Luku poistot[i] on välillä 0..m, ja se tulee tulkita siten, että kaupunkien mista[poistot[i]] ja minne[poistot[i]] välinen tie suljetaan. Jo suljettua tietä ei yritetä enää sulkea. Voit olettaa, ettei mikään tie esiinny kahta kertaa taulukoissa mista ja minne, eli kahden kaupungin välillä on korkeintaan yksi suora tie. Poistoja tehdään korkeintaan 105.

Metodin palauttaman taulukon komponentteja tulee olla yhtä pitkä kuin poistot -taulukon. Luvun komponetteja[i] pitää kertoa tieverkoston komponenttien määrä tien numero poistot[i] sulkemisen jälkeen. Kun tie on suljettu, ei sitä enää avata uudestaan.

Esimerkit

#metodin kutsuhaluttu palautusarvo
1komponentteja(3, new int[] {1,2,3}, new int[] {2,3,1}, new int[] {0,1,2}){1,2,3}
2komponentteja(5, new int[] {1,1,1,2,2,3,4}, new int[] {2,3,4,3,4,4,5}, new int[] {2,3,6,1,4}){1,1,2,2,3}
3komponentteja(5, new int[] {1,2,3,4}, new int[] {2,3,4,5}, new int[] {2,0,3,1}){2,3,4,5}
4komponentteja(5, new int[] {1,2,3,4,5}, new int[] {2,3,4,5,1}, new int[] {2,0,3,1}){1,2,3,4}

Tehtävä 5

Uolevin sedän huoltoaseman mainoskampanja (TMC4.5) ei juurikaan lisännyt huoltoaseman suosiota. Tämän vuoksi huoltoasemalle on suunnitteilla uusi mainosjuliste, tällä kertaa julisteelle ei ole muita vaatimuksia kuin se, että se on suorakulmion muotoinen, ja että sen voi liimata aitaan (suorassa). Mikä on suurin mahdollinen ala julisteelle?

Toteutus

Toteuta seuraava metodi:

long suurinAla(long[] aita)

Parametrina tuleva taulukko aita kuvaa laudassa käytettyjen aitojen korkeudet siinä järjestyksessä, missä ne esiintyvät aidassa. Aidassa on korkeintaan 105 aitaa, ja lautojen korkeudet ovat välillä 1..109. Jokainen lauta on metrin levyinen ja korkeudet annetaan metreinä. Palautettava pinta-ala tulee olla neliömetreinä.

Esimerkit

#metodin kutsuhaluttu palautusarvo
1suurinAla(new long[]{1, 2, 3, 4, 5})9
2suurinAla(new long[]{5, 4, 3, 2, 1})9
3suurinAla(new long[]{5, 5, 1, 5, 5, 4})12
4suurinAla(new long[]{1, 1, 1})3

Ohessa vielä merkittynä suurimmat mahdolliset julisteet kussakin esimerkissä:

Esim 1:
    x
   xx
  xxx
 xxxx
xxxxx

Esim 2:
x    
xx   
xxx  
xxxx 
xxxxx

Esim 3:
xx xx 
xx xxx
xx xxx
xx xxx
xxxxxx

Esim 4:
xxx