Viikko 4: TMC-tehtävät

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

Tällä ja kaikilla muillakin viikoilla on algoritmien pystyttävä tuottamaan oikea vastaus alle yhdessä sekunnissa, ellei erikseen muuta mainita. Viikon aiheena on jono- ja pinorakenteen soveltaminen. Javasta läytyvät valmiit toteutukset Stack ja ArrayDeque.


Tehtävä 1

Eräänä päivänä kävellessään puistossa Uolevi huomasi, että puistossa on monia hienoja kiviä. Koska Uolevi on ahkera kivien kerääjä, alkoi hän poimimaan maassa lojuvia kiviä. Hän kerää kivensä erityiseen kivikoteloon, johon kivet menevät sopivasti päällekkäin. Uusi kivi menee aina kotelon päällimmäiseksi.

Uolevi ei kuitenkaan halua kokoelmaansa useita samanlaisia kiviä, joten jos hän jossain vaiheessa huomaa, että uusi kivi on samanlainen kuin kotelon päällimmäinen kivi, heittää hän sekä kotelon päällimmäisen kiven, että uuden kiven pois. Tehtävänäsi on selvittää kuinka monta uutta kiveä Uolevilla on kävelynsä jälkeen.

Toteutus

Toteuta seuraava metodi:

int montakoKivea(int[] kivet)

Taulukko kivet sisältää Uolevin löytämät kivet löytämisjärjestyksessä. Kivet ovat samanlaiset jos niitä vastaavat kokonaisluvut ovat samat. Metodin tulee palauttaa uusien kivien määrä kävelyn jälkeen.

Taulukon kivet pituus on korkeintaan 100000 ja sen sisältämät luvut ovat välillä 0..109.

Esimerkit

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

Tehtävä 2

Sinulle on annettu merkkijono, joka muodostuu merkeistä ( ja ). Tehtäväsi on tarkistaa, onko merkkijono oikein sulutettu eli voiko merkkijonon saada matemaattisesta lausekkeesta poistamalla kaikki muut merkit paitsi sulut.

Esimerkiksi merkkijonot ((())) ja (())() ovat oikein sulutettuja, kun taas merkkijonot (()))( ja ())(() eivät ole oikein sulutettuja.

Toteutus

Toteuta seuraava metodi:

boolean sulutus(String mjono)

Parametri mjono on sulut sisältävä merkkijono. Sen pituus on välillä 1..105.

Metodin tulee palauttaa true, jos merkkijono on oikein sulutettu, ja muuten false.

Esimerkit

#metodin kutsuhaluttu palautusarvo
1sulutus("((()))")true
2sulutus("(())()")true
3sulutus("(()))(")false
4sulutus("())(()")false

Tehtävä 3

Tehtäväsi on toteuttaa pinolaskin, joka suorittaa annetun ohjelman. Pinoa voi käsitellä vain sen lopusta (oikealta puolelta). Aluksi pinossa on luku 1. Ohjelman komennot suoritetaan järjestyksessä, ja mahdolliset komennot ovat:

Esimerkiksi ohjelma @@+@* suoritetaan näin:

  1. Aluksi pinon sisältö on [1].
  2. Komennon @ jälkeen sisältö on [1, 1].
  3. Komennon @ jälkeen sisältö on [1, 1, 1].
  4. Komennon + jälkeen sisältö on [1, 2].
  5. Komennon @ jälkeen sisältö on [1, 2, 2].
  6. Komennon * jälkeen sisältö on [1, 4].

Tehtäväsi on suorittaa annettu ohjelma ja palauttaa pinon viimeinen luku ohjelman suorituksen jälkeen.

Toteutus

Toteuta seuraava metodi:

int laskin(String ohjelma)

Parametri ohjelma on suoritettava ohjelma. Se muodostuu merkeistä @, + ja *, ja sen pituus on 1..105 merkkiä.

Metodin tulee palauttaa pinon viimeinen luku ohjelman suorituksen jälkeen. Voit olettaa, että kaikki pinossa ohjelman suorituksen aikana olevat luvut, mukaan lukien viimeinen luku, ovat välillä 1..109. Pinolaskimen saama ohjelma on aina hyvin koodattu, eli kaikki operaatiot voidaan suorittaa ongelmitta, eli esimerkiksi merkin '+' kohdalla pinossa on vähintään kaksi lukua.

Esimerkit

#metodin kutsuhaluttu palautusarvo
1laskin("@@+@*")4
2laskin("@+")2
3laskin("@@**")1
4laskin("@+@+@+")8
5laskin("@@@+++")4

Tehtävä 4

Läheisen yökerhon korruptoitunut ovimies on päättänyt hankkia lisätienestejä kiristämällä jonottavia asiakkaita. Välillä hän veloittaa x euroa jokaiselta jonossa sillä hetkellä olevalta henkilöltä, ja koska kaikki jonottajat haluavat päästä sisään, maksavat he ovimiehelle aina hänen pyytämänsä summan. Tehtäväsi on auttaa ovimiestä pitämään kirjaa siitä, kuinka paljon hän on onnistunut saamaan rahaa kultakin asiakkaalta.

Toteutus

Tehtävänäsi on toteuttaa tehtäväpohjassa oleva luokka Laskuri ja siihen seuraavat metodit:

Testeissä luokan metodeja kutsutaan korkeintaan 500000 kertaa. Luku x on välillä 1..109. Jos jonossa ei ole asiakkaita, niin metodin long paastaSisaan() tulee palauttaa 0.


Tehtävä 5

Uolevin sedän huoltoasema haluaa saada näkyvyyttä autoilijoiden keskuudessa, joten läheisen tien laidalla olevaan aitaan halutaan liimata suorakulmion muotoinen mainosjuliste. Aidassa on kuitenkin yksi ongelma: se on rakennettu vaihtelevan korkuisista laudoista. Lisäksi tyyliseikkojen vuoksi julisteen on oltava oikeasta reunastaan juuri oikean korkuinen Mikä on suurin mahdollinen pinta-ala julisteelle?

Selittävä esimerkki

Jos aidan lautojen korkeudet ovat [3, 1, 4, 4, 5], eli aita näyttää tältä:

    x
  xxx
x xxx
x xxx
xxxxx
niin suurin kelpaava mainosjuliste on merkitty punaisella
    x
  xxx
x xxx
x xxx
xxxxx
ja sen ala on selkeästi 8. Seuraava juliste olisi suurempi
    x
  xxx
x xxx
x xxx
xxxxx
mutta se ei täytä vaatimusta oikean reudan oikeasta korkeudesta. Vasemmasta reunasta ei vaadita mitään, joten esimerkiksi
x    
xx   
xxx  
xxxx 
xxxxx
on kelvollinen juliste.

Toteutus

Toteuta metodi long suurinAla(long[] aita), joka palauttaa suurimman mahdollisen pinta-alan (neliömetreinä) kelpaavalle mainosjulisteelle. Syötteenä tulevassa taulukossa on kuvattuna aidan laudat vasemmalta oikealle siinä järjestyksessä, jossa ne esiintyvät tien laidalla. Jokainen lauta on metrin levyinen ja i:nnen laudan korkeus on aita[i] metriä.

Aidassa on korkeintaan 200000 lautaa ja lautojen korkeudet ovat välillä 1..109.

Tehtävässä alkuun auttava vinkki (valkoista tekstiä valkoisella pohjalla): tehtävää kannattaa lähestyä siten, että etsii jokaisella oikean reunan valinnalla leveimmän mahdollisen julisteen, jonka oikea päätepiste on valitussa kohdassa.

Esimerkkisyötteet

#metodin kutsuhaluttu palautusarvo
1suurinAla(new long[]{1, 2, 3, 4, 5})5
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