• Tidak ada hasil yang ditemukan

KEMENTERIAN PENDIDIKAN DAN KEBUDAYAAN

N/A
N/A
Protected

Academic year: 2021

Membagikan "KEMENTERIAN PENDIDIKAN DAN KEBUDAYAAN"

Copied!
77
0
0

Teks penuh

(1)

SOAL UJIAN

OLIMPIADE SAINS NASIONAL 2013

CALON PESERTA

INTERNATIONAL OLYMPIAD IN INFORMATICS (IOI) 2014

HARI KE-1

Waktu : 5 jam

KEMENTERIAN PENDIDIKAN DAN KEBUDAYAAN

DIREKTORAT JENDERAL PENDIDIKAN MENENGAH

DIREKTORAT PEMBINAAN SEKOLAH MENENGAH ATAS

TAHUN 2013

INFORMATIKA

Hak Cipta

(2)

1

Tebak Himpunan

Batas Waktu 1 detik

Batas Memori 32 MB

Deskripsi

Pak Dengklek kini sudah pensiun dan memiliki banyak cucu. Untuk mengisi waktu luangnya,

Pak Dengklek sering membuat permainan yang bisa dimainkan saat cucu-cucunya datang.

Saat liburan sekolah, cucu kesayangan Pak Dengklek berlibur ke rumahnya. Ternyata, ia telah

menyiapkan permainan baru untuk cucu kesayangannya tersebut! Permainannya adalah

sebagai berikut.

Pak Dengklek mengumumkan sebuah bilangan bulat positif N. Setelah itu, ia memilih

subhimpunan S dari {1, 2, ..., N}. Tugas sang cucu adalah menebak S dengan paling banyak

Q buah tebakan kepada Pak Dengklek. Setiap tebakan berupa sebuah subhimpunan T dari {1,

2, ..., N} yang harus memiliki setidaknya K anggota.

Untuk setiap tebakan, Pak Dengklek akan menjawab salah satu dari ketiga jawaban berikut:

YA, apabila S sama persis dengan T.

BISA JADI, apabila S tidak sama dengan T namun ada minimal satu anggota S yang

juga merupakan anggota T.

TIDAK, apabila tidak ada satupun anggota S yang juga merupakan anggota T.

Sebagai contoh, apabila N = 10, S = {2, 3, 5, 7}, dan K = 2:

Jika T = {2, 3, 5, 7}, maka Pak Dengklek menjawab YA.

Jika T = {2, 3, 7}, maka Pak Dengklek menjawab BISA JADI.

Jika T = {1, 2, 3, 5, 7}, maka Pak Dengklek menjawab BISA JADI.

Jika T = {2, 8}, maka Pak Dengklek menjawab BISA JADI.

Jika T = {1, 8, 9}, maka Pak Dengklek menjawab TIDAK.

Jika T = {4, 10}, maka Pak Dengklek menjawab TIDAK.

T = {5} tidak diperbolehkan karena banyak anggotanya kurang dari K.

Sekarang, Anda diminta membuat sebuah program interaktif yang dapat membantu cucu Pak

Dengklek memenangkan permainan ini.

Format Interaksi

Awalnya, program Anda harus membaca sebuah baris berisi string "Subsoal X", dengan X

adalah nomor subsoal. Kemudian, program Anda harus membaca tiga buah bilangan bulat N,

K, dan Q, dipisahkan oleh spasi. Setelah itu, program Anda dapat mengeluarkan paling

banyak Q buah tebakan dalam format:

M T

1

T

2

T

3

... T

M

yakni, sebuah bilangan bulat M diikuti dengan M buah bilangan bulat dipisahkan spasi, yang

berarti Anda memberi tebakan T = {T

1

, T

2

, ... T

M

}, dengan syarat:

K ≤ M ≤ N

T

1

< T

2

< ... < T

M

(3)

2

string yang mendeskripsikan jawaban Pak Dengklek. String tersebut dijamin selalu

merupakan salah satu dari:

"ya", artinya Pak Dengklek menjawab YA. Anda langsung dianggap benar dalam

kasus uji yang bersangkutan dan program Anda tidak perlu melakukan apa-apa lagi.

"bisajadi", artinya Pak Dengklek menjawab BISA JADI.

"tidak", artinya Pak Dengklek menjawab TIDAK.

Pastikan program Anda berhenti melakukan interaksi setelah menerima jawaban "ya".

Contoh Interaksi

Berikut adalah contoh interaksi program, dengan subhimpunan S yang dimiliki grader adalah

S = {2, 5, 6}.

Keluaran Program Peserta

Umpan Balik Grader

Subsoal 0

7 3 10

3 1 2 6

bisajadi

4 1 3 4 7

tidak

7 1 2 3 4 5 6 7

bisajadi

3 2 5 7

bisajadi

3 2 5 6

ya

(interaksi selesai)

Pembagian Subsoal

Pada semua subsoal, berlaku:

S memiliki setidaknya K buah anggota.

Subsoal 1 (6 poin)

N = 5

K = 1

Q = 32

Subsoal 2 (12 poin)

N = 6

(4)

3

K = 2

Q = 100

Khusus untuk subsoal 1 dan subsoal 2:

Hanya terdapat sebuah kasus uji (satu subsoal dinyatakan oleh satu kasus uji), yang

dapat dimainkan

di sini

.

Dalam permainan tersebut, banyaknya tebakan yang dapat diajukan tidak dibatasi.

Jika Anda sudah memenangkan permainan untuk subsoal tertentu, Anda dapat

memilih pilihan pada permainan untuk mengeluarkan source code yang dapat

langsung Anda kirimkan ke grader dan menjawab dengan benar pada subsoal yang

telah Anda menangkan.

Subsoal 3 (5 poin)

1 ≤ N ≤ 10

K = 1

Q = 2

N

Subsoal 4 (8 poin)

1 ≤ N ≤ 100

K = 1

Q = N + 1

Subsoal 5 (33 poin)

1 ≤ N ≤ 1.000

K = 1

Q = 2 × ceil(log

2

N) + 1

S selalu berupa {1, 2, ..., R} dengan R ≤ N

Subsoal 6 (36 poin)

2 ≤ N ≤ 100

K = 2

Q = N

2

Catatan

(5)

4

Sebuah himpunan V dikatakan merupakan subhimpunan dari himpunan S apabila

setiap anggota V juga merupakan anggota S.

Yang perlu diperhatikan adalah bahwa untuk tipe soal interaktif seperti ini, Anda harus selalu

memberikan perintah "fflush(stdout);" (bagi pengguna C/C++) atau "flush(output);"

(bagi pengguna PASCAL) setiap kali Anda mencetak keluaran (dengan kata lain, setiap kali

ada perintah mencetak keluaran misalnya write, writeln, printf, cout, atau puts, tepat di

bawahnya harus ada perintah fflush/flush).

Sebagai contoh, berikut adalah contoh source code dalam bahasa Pascal yang akan selalu

menebak semua N barang tanpa mempedulikan nilai N, K, dan Q yang diberikan.

var subsoal: string; N, K, Q, i: longint; begin readln(subsoal); readln(N, K, Q); write(N);

for i := 1 to N do write(' ', i); writeln;

flush(output); end.

Dan berikut adalah contoh source code dalam bahasa C++.

#include <cstdio> #include <cstring> char subsoal[100]; int nomor; int N, K, Q, i; int main() {

scanf("%s %d", subsoal, &nomor); scanf("%d %d %d", &N, &K, &Q);

(6)

5

for(i = 1; i <= N; i++) printf(" %d", i); printf("\n");

fflush(stdout);

return 0; }

Peringatan

Apabila program Anda melakukan salah satu dari hal-hal di bawah ini:

mengeluarkan tebakan atau menjawab tidak sesuai format sehingga tidak dikenali oleh

grader, atau

menebak lebih dari Q kali,

maka program Anda akan dihentikan secara otomatis dan Anda tidak memperoleh nilai pada

kasus uji yang bersangkutan.

Perhatikan bahwa untuk soal ini, jika solusi Anda dapat menyelesaikan subsoal X, tidak

dijamin bahwa solusi tersebut juga dapat menyelesaikan subsoal-subsoal Y dengan Y < X.

(7)

6

Berbaris Sebelum Masuk

Batas Waktu 1 detik

Batas Memori 32 MB

Deskripsi

Pak Dengklek adalah seorang wali murid di SD TOKI. Setiap pagi, para siswa diharuskan

untuk berbaris di depan pintu kelas sebelum masuk. Namun, Pak Dengklek memiliki sedikit

kesulitan karena tiap siswa memiliki keinginan tersendiri dalam berbaris.

Terdapat N orang siswa di SD tersebut, dinomori dari 1 sampai dengan N. Siswa nomor 1

berada di paling depan dan siswa nomor N berada di paling belakang barisan. Siswa ke-i

memiliki tinggi badan sebesar T

i

satuan. Setiap siswa ke-i ingin agar saat ia berbaris,

banyaknya siswa di depannya yang memiliki tinggi badan kurang dari atau sama dengan

tinggi badannya, berada di antara A

i

dan B

i

orang siswa, inklusif.

Bantulah Pak Dengklek membariskan siswa-siswanya dalam satu baris sedemikian sehingga

semua keinginan siswanya terpenuhi.

Format Masukan

Baris pertama pada berkas masukan berisi string "Subsoal X" dengan X menyatakan nomor

subsoal.

Baris kedua berisi sebuah bilangan bulat N. N baris berikutnya masing-masing berisi 3 buah

bilangan bulat T

i

, A

i

, dan B

i

.

Format Keluaran

Keluarkan salah satu barisan yang memenuhi, dalam format

S

1

S

2

S

3

... S

N

dengan S

i

adalah nomor siswa yang berada pada posisi ke-i dari depan.

Contoh Masukan

Subsoal 0 3 150 1 3 160 2 2 140 0 2

Contoh Keluaran

3 1 2

Pembagian Subsoal

Pada semua subsoal, berlaku:

(8)

7

0 ≤ A

i

≤ B

i

≤ N

Semua nilai T

i

berbeda-beda

Dijamin ada setidaknya sebuah barisan yang memenuhi syarat

Subsoal 1 (9 poin)

Hanya terdapat sebuah kasus uji, yang dapat diunduh

di sini

.

Subsoal 2 (20 poin)

Hanya terdapat sebuah kasus uji, yang dapat diunduh

di sini

.

Subsoal 3 (21 poin)

1 ≤ N ≤ 8

Subsoal 4 (50 poin)

1 ≤ N ≤ 1.000

(9)

8

Lipat Kertas

Batas Waktu 0,2 detik

Batas Memori 32 MB

Deskripsi

Pak Dengklek sekarang sedang sibuk memainkan kertas origami buatan Pak Ganesh yang

berbentuk persegi panjang dengan ukuran 1 × N petak berwarna-warni. Petak warna paling

kiri disebut petak 1, di kanannya disebut petak 2, dan seterusnya. Kertas origami ini unik,

karena bagian yang dapat dilipat hanyalah sisi persinggungan 2 buah petak saja. Dengan

demikian, terdapat N − 1 lekukan yang dapat dilipat.

Pak Ganesh sebelumnya telah melipat-lipat kertasnya menjadi berukuran 1 × 1 (tentu

hasilnya sangatlah tebal!). Kemudian, Pak Ganesh membuka lipatan-lipatan kertas tersebut.

Hasilnya, kertas tersebut memiliki bekas lekukan-lekukan pada bagian yang dilipat dan

lekukan-lekukan tersebut menjadi cekungan ke atas ataupun cekungan ke bawah.

Gambar di atas merupakan kondisi kertas yang dibuka dari lipatannya dan dilihat dari sisi

samping ketika permukaan kertas menghadap ke atas dan petak nomor 1 berada di paling kiri.

Kali ini Pak Ganesh tidak lagi memberikan Pak Dengklek kertas yang dibuka dari lipatannya,

melainkan Pak Ganesh memberikan urutan petak warna hasil akhir lipatan apabila dilihat dari

samping kertas ketika permukaan kertas menghadap ke atas dan petak nomor 1 berada di

paling kiri. Pak Dengklek diminta untuk mencari tahu bagaimana kondisi lekukan kertas

tersebut apabila dibuka dari lipatannya!

(10)

9

Format Masukan

Baris pertama pada berkas masukan berisi string "Subsoal X" (tanpa tanda kutip) dengan X

menyatakan nomor subsoal. Baris kedua berisi sebuah bilangan bulat N, yaitu banyaknya

petak warna-warni pada kertas. Baris ketiga berisi N buah bilangan bulat dipisahkan spasi,

yaitu urutan petak warna hasil akhir lipatan apabila dilihat dari sisi samping kertas ketika

permukaan kertas menghadap ke atas dan petak nomor 1 berada di paling kiri..

Format Keluaran

Keluaran terdiri dari 1 baris yang berisi string S.

String S memiliki panjang N − 1 karakter yang menunjukkan kondisi kertas setelah dibuka

dari lipatannya. Karakter ke-i pada S menunjukkan lekukan di antara petak i dan petak i + 1.

Karakter 'A' menunjukkan lekukan tersebut berupa cekungan ke atas, dan karakter 'B'

menunjukkan lekukan tersebut berupa cekungan ke bawah.

Apabila tidak ada kemungkinan solusi, S berisi string “INVALID” (tanpa tanda kutip). Apabila

terdapat lebih dari satu kemungkinan solusi, keluarkan yang mana saja.

Contoh Masukan 1

Subsoal 0 8 1 8 5 4 3 6 7 2

Contoh Keluaran 1

BBABBAA

Contoh Masukan 2

Subsoal 0 4 4 1 3 2

Contoh Keluaran 2

INVALID

Penjelasan Contoh Kasus Uji

Gambar berikut adalah kondisi kertas yang ditunjukkan oleh string S pada contoh keluaran 1.

(11)

10

Selanjutnya, lipatlah bagian antara petak 2 dan petak 3 maupun bagian antara petak 7 dan

petak 6.

Terakhir, lipatlah lipatan bagian yang tersisa.

Didapat hasil akhir lipatan dengan urutan petak warna : 1 8 5 4 3 6 7 2 (dilihat dari bagian

atas ke bawah), yang merupakan urutan petak warna yang ditanyakan oleh Pak Ganesh pada

contoh masukan 1.

Perhatikan bahwa apabila kertas tersebut dibuka kembali, maka kondisi lekukan kertas tidak

berbeda dengan kondisi lekukan kertas sebelum dilipat. Sehingga, lekukan kertas tersebut

merupakan salah satu solusi yang mungkin.

Pembagian Subsoal

Subsoal 1 (9 poin)

Hanya terdapat sebuah kasus uji, yang dapat diunduh

di sini

.

Subsoal 2 (9 poin)

(12)

11

Subsoal 3 (30 poin)

2 ≤ N ≤ 1.000

Tidak ada masukan dengan keluaran INVALID

Subsoal 4 (7 poin)

2 ≤ N ≤ 4

Subsoal 5 (28 poin)

2 ≤ N ≤ 1.000

Subsoal 6 (17 poin)

2 ≤ N ≤ 100.000

(13)

12

Menggelindingkan Kubus

Batas Waktu 1 detik

Batas Memori 32 MB

Deskripsi

Diberikan sebuah kubus yang masing-masing muka sisinya dinomori antara 1 hingga 6,

inklusif. Kubus itu diletakkan pada bidang datar yang luasnya tidak terbatas.

Pada mulanya, masing-masing sisi kubus itu menghadap ke arah atas, bawah, utara, timur,

selatan, dan barat yang secara berturut-turut dinomori dengan P

1

, P

2

, P

3

, P

4

, P

5

, dan P

6

.

Anda diperbolehkan menggelindingkan kubus itu ke arah utara, timur, barat, atau selatan.

Akibat dari menggelindingkan kubus sekali adalah perubahan konfigurasi nomor pada muka

sisinya yang tergantung pada arah kubus digelindingkan.

Berikut ini adalah contoh sebuah kubus yang kebetulan dibuat mirip dengan dadu. Setiap

langkah dilakukan sekali dan merupakan lanjutan dari langkah sebelumnya.

Muka Kubus

Awal

Digelindingkan

ke Utara

Kemudian

ke Timur

Kemudian

ke Selatan

Kemudian

ke Barat

P

1

(atas)

1

5

3

1

5

P

2

(bawah)

6

2

4

6

2

P

3

(utara)

2

1

1

4

4

P

4

(timur)

4

4

5

5

6

P

5

(selatan)

5

6

6

3

3

P

6

(barat)

3

3

2

2

1

Tugas Anda adalah menggelindingkan kubus dengan sesedikit mungkin langkah sedemikian

sehingga konfigurasi nomor-nomor pada muka sisi atas, bawah, utara, timur, selatan, dan

barat secara berturut-turut menjadi Q

1

, Q

2

, Q

3

, Q

4

, Q

5

, dan Q

6

.

Format Masukan

Baris pertama pada berkas masukan berisi string "Subsoal X" dengan X menyatakan nomor

subsoal. Baris kedua berisi 6 buah bilangan bulat dipisahkan spasi yang secara berturut-turut

menyatakan P

1

, P

2

, P

3

, P

4

, P

5

, dan P

6

. Baris ketiga berisi 6 buah bilangan bulat dipisahkan

spasi yang secara berturut-turut menyatakan Q

1

, Q

2

, Q

3

, Q

4

, Q

5

, dan Q

6

.

Format Keluaran

Sebuah baris berisi sebuah bilangan bulat yang menyatakan banyaknya langkah

penggelindingan yang diperlukan agar tujuan seperti pada deskripsi soal tercapai dan

banyaknya langkah penggelindingan tersebut minimal.

Contoh Masukan

Subsoal 0 1 4 3 2 3 4

(14)

13

3 3 4 4 2 1

Contoh Keluaran

2

Penjelasan Contoh Kasus Uji

Pada contoh masukan, salah satu cara untuk mendapatkan konfigurasi akhir dalam dua

langkah adalah gelindingkan kubus ke barat, kemudian ke selatan. Setelah langkah pertama,

konfigurasi kubus adalah 2 4 3 4 3 1.

Pembagian Subsoal

Pada semua subsoal, berlaku:

Nilai-nilai Q

1

,Q

2

, Q

3

, Q

4

, Q

5

, dan Q

6

adalah sedemikian sehingga terdapat cara

untuk mencapai konfigurasi akhir.

Subsoal 1 (8 poin)

Hanya terdapat sebuah kasus uji, dan dapat diunduh

di sini

.

Subsoal 2 (10 poin)

Hanya terdapat sebuah kasus uji, dan dapat diunduh

di sini

.

Subsoal 3 (16 poin)

P

1

= 2

P

2

= 2

P

3

= 1

P

4

= 1

P

5

= 1

P

6

= 1

Subsoal 4 (24 poin)

P

1

= 2

P

2

= 1

P

3

= 1

P

4

= 1

P

5

= 1

(15)

14

P

6

= 1

Subsoal 5 (42 poin)

Untuk setiap i, 1 ≤ P

i

≤ 6.

(16)

SOLUSI UJIAN

OLIMPIADE SAINS NASIONAL 2013

CALON PESERTA

INTERNATIONAL OLYMPIAD IN INFORMATICS (IOI) 2014

HARI KE-1

Waktu : 5 jam

KEMENTERIAN PENDIDIKAN DAN KEBUDAYAAN

DIREKTORAT JENDERAL PENDIDIKAN MENENGAH

DIREKTORAT PEMBINAAN SEKOLAH MENENGAH ATAS

TAHUN 2013

INFORMATIKA

Hak Cipta

(17)

Solusi Hari-1 - 1

Tebak Himpunan

Batas Waktu: 1 detik

Batas Memory: 32 MB

#include <iostream> #include <cstdio> #include <algorithm> #include <cmath> #include <cstring> #include <string> #include <queue> #include <stack> #include <vector> #include <utility> #include <map>

#define REP(a,b) for (int a=0; a<b; a++) #define FOR(a,b,c) for (int a=b; a<=c; a++) #define FORD(a,b,c) for (int a=b; a>=c; a--) #define RESET(a,b) memset(a, b, sizeof a) #define EPS 1e-9

#define INF 2123123123 #define LL long long #define F first #define S second #define MP make_pair #define PB push_back #define PII pair<int,int>

#define PDD pair<double,double> #define __ puts("") using namespace std; int n,k,q; char sc[1000]; void on(){ bool ada[105]; RESET(ada,0); REP(i,n){ printf("1 %d\n", i+1); fflush(stdout); scanf("%s", sc); if (sc[0] != 't'){ ada[i] = 1; } } int cnt = 0; REP(i,n){ if (ada[i]) cnt++; } printf("%d", cnt); REP(i,n){

(18)

Solusi Hari-1 - 2

} printf("\n"); fflush(stdout); //must be true } void ologn(){ int ki,ka,tgh,ans; //ONE ki = 1; ka = n;

while (ki <= ka){

tgh = (ki + ka) >> 1; //ada: tgh? printf("1 %d\n", tgh); fflush(stdout); int h = 0; scanf("%s", sc); if (sc[0] != 't'){ h = 1; } if (h){ ans = tgh; ki = tgh + 1; }else{ ka = tgh - 1; } } printf("%d", ans); FOR(i,1,ans){ printf(" %d", i); } printf("\n"); fflush(stdout); //must be true } void grim(){ //eleminate all 0s bool ada[105]; FOR(i,1,n){ ada[i] = 1; } FOR(i,1,n){ FOR(j,i+1,n){ printf("2 %d %d\n", i, j); fflush(stdout); scanf("%s", sc); if (sc[0] == 't'){ //haha! ada[i] = 0; ada[j] = 0; }

(19)

Solusi Hari-1 - 3

} } //odd 0 or even 0? int cnt = 0; int h0 = 0; FOR(i,1,n){ if (ada[i]) cnt++; else h0++; } printf("%d", cnt); FOR(i,1,n){

if (ada[i]) printf(" %d", i); } printf("\n"); fflush(stdout); scanf("%s", sc); if (sc[0] == 'y'){ //sweet, even 0 return; }else{

//some work needed, it is odd 0! int liar = -1; FOR(i,1,n){ if (ada[i]){ printf("%d", cnt-1); FOR(j,1,n){ if (j != i && ada[j]){ printf(" %d", j); } } printf("\n"); fflush(stdout); bool h = 0; scanf("%s", sc); if (sc[0] == 'y'){ return; } } } } } int main(){ gets(sc);

scanf("%d %d %d", &n, &k, &q); if (k == 1){ if (q > n){ on(); }else{ ologn(); } }else{ grim(); } return 0; }

(20)

Solusi Hari-1 - 4

Berbaris Sebelum Masuk

Batas Waktu: 1 detik

Batas Memory: 32 MB

#include<iostream> #include<cstring> #include<cstdio> #include<vector> #include<queue> #include<utility> #include<cassert> #include<algorithm> #define S 1000 #define N 1000 using namespace std; char asal[100]; int kasus,banyak; pair<int,int> batas[N+5]; vector<int> orang[S+5]; bool ada[S+5]; int jawab[N+5],prev[N+5];

bool cf(const int &a,const int &b) { return (batas[a] <= batas[b]); }

int main() {

assert(scanf("%s %d",asal,&kasus) == 2); assert(scanf("%d",&banyak) == 1);

assert(1 <= banyak && banyak <= N); assert(0 <= kasus && kasus <= 4); assert(strcmp(asal,"Subsoal") == 0); if (kasus == 3) assert(banyak <= 8);

memset(ada,0,sizeof(ada));

for (int i=0,sem;i<banyak;++i) {

assert(scanf("%d %d %d",&sem,&batas[i].first,&batas[i].second) == 3);

assert(0 <= batas[i].first && batas[i].first <= batas[i].second && batas[i].second <= banyak);

assert(1 <= sem && sem <= S); assert(!ada[sem]);

ada[sem] = true;

orang[sem].push_back(i); }

for (int i=1;i<=S;++i) sort(orang[i].begin(),orang[i].end(),cf);

int masuk = 0;

for (int i=1;i<=S;++i) {

if (orang[i].size() == 0) continue;

priority_queue<pair<int,int>,vector<pair<int,int> >,greater<pair<int,int> > > pq;

(21)

Solusi Hari-1 - 5

for (int j=0;j<masuk;++j) { prev[j] = jawab[j]; jawab[j] = 0; } int indeks1 = 0; int indeks2 = 0;

for (int j=0;j<masuk + orang[i].size();++j) { while (indeks2 < (int)orang[i].size() && batas[orang[i][indeks2]].first == j) { pq.push(make_pair(batas[orang[i][indeks2]].second,orang[i][indeks2])); ++indeks2; } if (pq.size() > 0) { jawab[j] = pq.top().second; pq.pop(); } else { jawab[j] = prev[indeks1]; ++indeks1; } } masuk += orang[i].size(); } assert(masuk == banyak); printf("%d",jawab[0]+1);

for (int i=1;i<banyak;++i) printf(" %d",jawab[i]+1); printf("\n");

return 0; }

(22)

Solusi Hari-1 - 6

Lipat Kertas

Batas Waktu: 0,2 detik

Batas Memory: 32 MB

#include <cstdio> #include <cstdlib> #include <stack> #include <cassert> #include <algorithm> using namespace std; int n,i,x,size,sub; int pos[1000007],bracket[1000007]; bool valid,udah[1000007]; char s[100]; int st[1000007]; int main() { scanf("%s%d",s,&sub); // Kasus scanf("%d",&n);

if (sub == 3) assert(2 <= n && n <= 1000); if (sub == 4) assert(2 <= n && n <= 4); if (sub == 5) assert(2 <= n && n <= 1000); if (sub == 6) assert(2 <= n && n <= 100000);

for (i=1 ; i<=n ; i++) { scanf("%d",&x);

assert(1 <= x && x <= n); //printf("%d\n",i);

assert(udah[x] == false); udah[x] = true;

pos[x] = i; // Simpan posisinya saja }

valid = true;

for (i=2 ; i<=n ; i+=2) { bracket[pos[i]] = i; bracket[pos[i-1]] = i; }

for (i=1 ; i<=n ; i++) if (bracket[i] != 0) { if (size == 0 || bracket[i] != st[size-1]) { st[size] = bracket[i];

size++; } else size--; }

if (size != 0) valid = false;

for (i=1 ; i<=n ; i++) bracket[i] = 0; size = 0;

for (i=3 ; i<=n ; i+=2) { bracket[pos[i]] = i;

(23)

Solusi Hari-1 - 7

bracket[pos[i-1]] = i; }

for (i=1 ; i<=n ; i++) if (bracket[i] != 0) { if (size == 0 || bracket[i] != st[size-1]) { st[size] = bracket[i];

size++; } else size--; }

if (size != 0) valid = false;

if (!valid) printf("INVALID\n"); else { for (i=1 ; i<n ; i++) {

if (i % 2 == 1) {

if (pos[i] < pos[i+1]) printf("A"); else printf("B"); } else {

if (pos[i] < pos[i+1]) printf("B"); else printf("A"); } } printf("\n"); } //sort(pos+1,pos+1+n);

//for (i=1 ; i<=n ; i++) swap(pos[i],pos[(13*i+42)%100]); }

(24)

Solusi Hari-1 - 8

Menggelindingkan Kubus

Batas Waktu: 0,2 detik

Batas Memory: 32 MB

#include <cstdio> #include <iostream> #include <vector> #include <algorithm> #include <stack> #include <queue> #include <map> #include <set> #include <utility> #include <sstream> #include <string> #include <iomanip> #include <cmath> #include <cstdlib> #include <cstring> using namespace std; #define fi first #define sc second #define MP make_pair #define pb push_back

#define PI acos(-1.0) //alternative #define PI (2.0 * acos(0.0)) #define vi vector<int>

#define vii vector<ii>

#define ALL(c) (c).begin(), (c).end()

#define RESET( c,a ) memset( (c), a, sizeof(c) ) #define REP( a,b,c ) for ( int a=b, _c=c; a<_c; ++a ) #define RED( a,b,c ) for ( int a=b, _c=c; a>=_c; --a )

#define REPI( it, c ) for ( __typeof( (c).begin() ) it=(c).begin(); it!=(c).end(); ++it )

const int big = 2000000000; const double INF = 1e9; const double EPS = 1e-9;

typedef long long LL; typedef pair<int,int> pii; typedef pair<LL,LL> pLL;

#define _DEBUG 1 #ifdef _DEBUG

#define DEBUG printf #else

#define DEBUG if (0) printf #endif

// NTU The Lyons' Template

//--- class dice { public: int i[6];

(25)

Solusi Hari-1 - 9

dice()

{ REP(x,0,6) i[x]=0; }

dice( int a[] )

{ REP(x,0,6) i[x]=a[x]; }

dice rot( int a ) {

int z = i[0]; dice ret;

REP(x,0,6) ret.i[x] = i[x]; if (a==1) //utara { ret.i[0] = i[4]; ret.i[4] = i[1]; ret.i[1] = i[2]; ret.i[2] = z; }

else if (a==2) //timur { ret.i[0] = i[3]; ret.i[3] = i[1]; ret.i[1] = i[5]; ret.i[5] = z; }

else if (a==3) //selatan { ret.i[0] = i[2]; ret.i[2] = i[1]; ret.i[1] = i[4]; ret.i[4] = z; }

else if (a==4) //barat { ret.i[0] = i[5]; ret.i[5] = i[1]; ret.i[1] = i[3]; ret.i[3] = z; } return ret; }

bool operator== (dice cmp) {

REP(x,0,6)

if (i[x] != cmp.i[x]) return false; return true;

} };

bool ud[8][8][8][8][8][8]; bool cek( dice a )

{

bool &lho = ud[a.i[0]][a.i[1]][a.i[2]][a.i[3]][a.i[4]][a.i[5]], ret = lho;

if (!lho) lho = true; return ret;

}

(26)

Solusi Hari-1 - 10

int main() { int S; scanf("Subsoal %d", &S); int i[6], h[6];

REP(x,0,6) scanf("%d", &h[x]); REP(x,0,6) scanf("%d", &i[x]); if (S==1) printf("2\n"); else if (S==2) printf("3\n"); else if (S==3) {

if ((i[0]==2) && (i[1]==2)) printf("0\n"); else printf("1\n"); } else if (S==4) { if (i[0]==2) printf("0\n"); else if (i[1]==2) printf("2\n"); else printf("1\n"); } else { RESET( ud,0 ); dice cur = dice(h), fin = dice(i); queue <dice> q; int o = 0; q.push( cur ); while (!q.empty()) { int SZ = q.size(); while (SZ--) {

cur = q.front(); q.pop(); if (!cek(cur)) { if (cur == fin) { printf("%d\n",o); return 0; } } q.push( cur.rot(1) ); q.push( cur.rot(2) ); q.push( cur.rot(3) ); q.push( cur.rot(4) ); } ++o; } } return 0; }

(27)

SOAL UJIAN

OLIMPIADE SAINS NASIONAL 2013

CALON PESERTA

INTERNATIONAL OLYMPIAD IN INFORMATICS (IOI) 2014

HARI KE-2

Waktu : 5 jam

KEMENTERIAN PENDIDIKAN DAN KEBUDAYAAN

DIREKTORAT JENDERAL PENDIDIKAN MENENGAH

DIREKTORAT PEMBINAAN SEKOLAH MENENGAH ATAS

TAHUN 2013

INFORMATIKA

Hak Cipta

(28)

1

Mengosongkan Matriks

Batas Waktu 1 detik

Batas Memori 32 MB

Deskripsi

Di sela-sela waktu santai sore, Pak Dengklek memberikan sebuah tantangan bagi

bebek-bebeknya. Pak Dengklek akan memberikan sebuah matriks berukuran N × M (N baris × M

kolom) berisi bilangan-bilangan. Baris-baris dinomori dari 1 sampai dengan N dari atas ke

bawah. Kolom-kolom dinomori dari 1 sampai dengan M dari kiri ke kanan. Kemudian, pada

setiap langkah, para bebek dapat melakukan salah satu dari 3 operasi di bawah ini pada

matriks tersebut.

1. Memilih sebuah bilangan bulat a kemudian menambahkan semua bilangan pada salah

satu kolom dengan a.

2. Memilih sebuah bilangan bulat b kemudian mengurangi semua bilangan pada salah

satu kolom dengan b.

3. Memilih sebuah bilangan bulat k kemudian mengalikan semua bilangan pada salah

satu baris dengan 2

k

.

Kemudian setiap bilangan hasil operasi tersebut akan dimodulo dengan 1.000.000.007 (10

9

+

7) .

Yang harus dilakukan oleh para bebek adalah menerapkan serangkaian operasi di atas

sedemikian sehingga pada akhirnya semua bilangan dalam matriks tersebut bernilai 0.

Sebagai contoh, perhatikan matriks yang diberikan Pak Dengklek di bawah ini.

Salah satu rangkaian operasi yang dapat diterapkan oleh para bebek adalah sebagai berikut.

No

Operasi

Hasil Matriks

1 Mengalikan bilangan pada baris 2 dengan 2 (k = 1)

2 Mengurangi bilangan pada kolom 1 dengan 1

3 Mengalikan bilangan pada baris 2 dengan 2 (k = 1)

(29)

2

No

Operasi

Hasil Matriks

5 Menambahkan bilangan pada kolom 2 dengan 1

6 Mengalikan bilangan pada baris 2 dengan 2 (k = 1)

7 Mengurangi bilangan pada kolom 2 dengan 1

8 Mengalikan bilangan pada baris 2 dengan 2 (k = 1)

9 Mengurangi bilangan pada kolom 2 dengan 2

Karena Pak Dengklek menyediakan bonus makanan ringan bagi yang berhasil memecahkan

tantangan ini, para bebek pun berlomba-lomba untuk mencari jawabannya. Agar para bebek

tidak terlalu lama dalam memikirkan solusi tantangan ini, Pak Dengklek membatasi

banyaknya operasi yang dapat dilakukan maksimum sebesar 100.000 operasi.

Rupa-rupanya, Kwek si bebek nakal bermaksud curang dengan meminta bantuan kepada

Anda. Walaupun Anda tidak bermaksud membantunya, Anda sendiri akhirnya juga merasa

penasaran dengan tantangan pak Dengklek dan ingin memecahkannya.

Format Masukan

Baris pertama pada berkas masukan berisi string “Subsoal X” dengan X menyatakan nomor

subsoal dari berkas masukan saat ini. Kemudian di baris kedua terdapat 2 buah bilangan bulat

yang dipisahkan oleh tepat sebuah spasi, yaitu N dan M .

N buah baris berikutnya mendeskripsikan matriks yang diberikan oleh Pak Dengklek dan

pada masing-masing baris terdapat tepat M buah bilangan bulat dipisahkan spasi.

Format Keluaran

Untuk masukan yang diberikan, pada baris pertama cetak sebuah bilangan S,

yang menyatakan banyaknya operasi yang Anda perlukan untuk mengubah semua bilangan

matriks pada berkas masukan menjadi 0.

Kemudian cetak S baris. Masing-masing baris menyatakan operasi yang dilakukan terhadap

matriks yang diberikan (sesuai urutan operasi tersebut diterapkan kepada matriks), dengan

format:

1. Jika operasi tersebut adalah menambahkan semua bilangan pada suatu kolom dengan

suatu bilangan, cetak "1 c a" (tanpa tanda kutip) dengan c menyatakan nomor kolom

yang ditambah dan a menyatakan besar bilangan yang ditambahkan.

(30)

3

dengan suatu bilangan, cetak "2 c b" (tanpa tanda kutip) dengan c menyatakan

nomor kolom yang dikurangi dan b menyatakan besar bilangan yang dikurangkan.

3. Jika operasi tersebut adalah mengalikan semua bilangan pada suatu baris tertentu

dengan 2

k

, cetak "3 r k" (tanpa tanda kutip) dengan r menyatakan nomor baris yang

dikali dan k menyatakan besaran pangkat dari 2.

Untuk setiap operasi, harus berlaku 0 ≤ a, b, k < 1.000.000.007.

Contoh Masukan

Subsoal 0 2 2 3 2 1 0

Contoh Keluaran

9 3 2 1 2 1 1 3 2 1 2 1 2 1 2 1 3 2 1 2 2 1 3 2 1 2 2 2

Pembagian Subsoal

Pada semua subsoal, berlaku:

Setiap anggota matriks berupa bilangan bulat nonnegatif kurang dari 1.000.000.007.

Subsoal 1 (11 poin)

Hanya terdapat sebuah kasus uji, yang dapat diunduh

di sini

.

Subsoal 2 (13 poin)

Hanya terdapat sebuah kasus uji, yang dapat diunduh

di sini

.

Subsoal 3 (7 poin)

N = 1

1 ≤ M ≤ 20

Subsoal 4 (41 poin)

1 ≤ N ≤ 20

M = 1

(31)

4

Subsoal 5 (28 poin)

1 ≤ N, M ≤ 20

(32)

5

Kontes Menari

Batas Waktu 2 detik

Batas Memori 32 MB

Deskripsi

Kwek, salah satu bebek Pak Dengklek, sedang berlatih tari tradisional yaitu Tari Bebek.

Tujuan Kwek berlatih tak lain dan tak bukan adalah untuk mengikuti kontes tahunan Tari

Bebek.

Dalam lomba, setiap peserta menampilkan beberapa macam gerakan Tari Bebek untuk

memikat para juri dengan keindahannya. Kwek sendiri sudah menguasai N macam gerakan

yang dinomori dari 1 sampai dengan N. Tiap gerakan memiliki nilai dasar keindahan.

Gerakan ke-i memiliki nilai dasar keindahan D

i

.

Terdapat empat jenis gerakan dalam Tari Bebek, yaitu gerakan biasa, gerakan memukau,

gerakan melelahkan, dan gerakan meyakinkan. Dijamin hanya terdapat sebuah gerakan

meyakinkan dalam Tari Bebek.

Dalam kontes Tari Bebek, setiap peserta harus memilih tepat R buah gerakan yang

berbeda-beda untuk ditampilkan, yang masing-masing dilakukan selama 1 menit. Nomor dari gerakan

yang dilakukan pada menit ke-t (untuk 1 ≤ t ≤ R) dinyatakan oleh G

t

. Setelah menampilkan

gerakan G

t

peserta akan mendapatkan skor K

t

yang besarnya dipengaruhi oleh D

Gt

dan

gerakan-gerakan sebelumnya, yang selengkapnya dihitung menurut aturan berikut.

1. Mula-mula, nilai K

t

adalah D

Gt

(yakni, nilai dasar keindahan gerakan nomor G

j

).

2. a. Jika t > 1 dan gerakan G

t-1

adalah gerakan memukau, maka nilai K

t

dikalikan dua.

b. Jika t > 1 dan gerakan G

t-1

adalah gerakan melelahkan, maka nilai K

t

dibagi dua

(dibulatkan ke bawah).

3. Jika untuk suatu m < t, gerakan G

m

adalah gerakan meyakinkan, maka

nilai K

t

ditambah sebesar Y.

Untuk kontes Tari Bebek tahun ini, telah diundang J orang juri yang dinomori dari 1 sampai

dengan J. Masing-masing juri menetapkan nilai batas keindahan. Juri ke-i menetapkan nilai

batas keindahan sebesar H

i

. Juri ke-i akan terkesima dengan tarian peserta jika K

1

+ K

2

+ ...

+ K

R

> H

i

.

Berikut ini adalah contoh rangkaian gerakan beserta simulasi perhitungan nilai keindahan

dari setiap gerakan tersebut, dengan R = 6.

t D

Gt

Jenis Gerakan G

t

K

t

1 10 biasa

10

2 5 meyakinkan (Y = 3) 5

3 12 biasa

12 + 3 = 15

4 5 memukau

5 + 3 = 8

5 7 melelahkan

(7 × 2) + 3 = 17

6 9 biasa

(9 / 2) + 3 = 4 + 3 = 7

(33)

6

t D

Gt

Jenis Gerakan G

t

K

t

K

1

+ K

2

+ ... + K

6

62

Diberikan daftar gerakan yang dikuasai oleh Kwek, dan juga batas nilai keindahan

masing-masing juri yang hadir. Tentukan banyaknya kemungkinan rangkaian gerakan Tari Bebek

berbeda yang dapat ditampilkan oleh Kwek untuk membuat masing-masing juri terkesima.

Format Masukan

Baris pertama pada berkas masukan berisi string "Subsoal X" dengan X menyatakan nomor

subsoal.

Baris kedua masukan berisi empat buah bilangan bulat N, R, Y, dan J, masing-masing

dipisahkan oleh spasi.

N baris berikutnya masing-masing berisi informasi gerakan yang dikuasai Kwek. Tiap baris

terdiri dari sebuah buah bilangan bulat D

i

dan sebuah karakter T

i

dipisahkan oleh spasi, yang

menyatakan nilai keindahan dari gerakan ke-i dan jenis dari gerakan tersebut. T

i

selalu

merupakan salah satu dari 'B', 'P', 'L', dan 'Y', yang secara berurutan menyatakan gerakan

biasa, memukau, melelahkan, dan meyakinkan.

J baris berikutnya masing-masing berisi sebuah bilangan bulat H

i

yang menyatakan nilai

batas keindahan dari juri ke-i.

Format Keluaran

Keluarkan J buah baris. Baris ke-i harus berisi banyaknya kemungkinan rangkaian gerakan

Tari Bebek yang dapat dibawakan oleh Kwek agar dapat membuat juri ke-i terkesima.

Contoh Masukan

Subsoal 0 5 2 5 3 10 B 15 B 5 P 300 L 7 B 1 1000 600

Contoh Keluaran

20 0 1

Penjelasan Contoh Kasus Uji

Untuk juri pertama, karena batas nilai keindahannya hanya 1, semua permutasi dari dua

gerakan yang ada dapat membuatnya terkesima.

(34)

7

terkesima.

Untuk juri ketiga, hanya ada satu cara yang dapat membuat juri tersebut terkesima yaitu

menampilkan gerakan 3 kemudian dilanjutkan gerakan 4. Total keindahannya adalah 5 + (2 ×

300) = 605.

Pembagian Subsoal

Pada semua subsoal, berlaku:

1 ≤ N ≤ 10

0 < R ≤ N

0 ≤ Y ≤ 100

1 ≤ H

i

≤ 100.000

1 ≤ D

i

≤ 1.000

Dijamin bahwa hanya terdapat paling banyak satu buah gerakan meyakinkan pada

masukan.

Subsoal 1 (9 poin)

Hanya terdapat sebuah kasus uji, yang dapat diunduh

di sini

.

Subsoal 2 (9 poin)

Hanya terdapat sebuah kasus uji, yang dapat diunduh

di sini

.

Subsoal 3 (17 poin)

1 ≤ J ≤ 10

Semua gerakan pada masukan merupakan gerakan biasa.

Subsoal 4 (27 poin)

1 ≤ J ≤ 10

Subsoal 5 (38 poin)

1 ≤ J ≤ 1.000

(35)

8

Cuti Liburan

Batas Waktu 1 detik

Batas Memori 32 MB

Deskripsi

Karena sedikit jenuh dengan pekerjaannya di Kantor Bebek, minggu ini Pak Dengklek

mengajukan cuti liburan. Beruntungnya, atasan Pak Dengklek langsung menyetujui cuti

tersebut. Pak Dengklek sangat senang dan langsung mempersiapkan segala sesuatu untuk

liburannya mendatang.

Salah satu hal yang Pak Dengklek persiapkan adalah koper berisi baju-bajunya selama

liburan. Saat ini, ia memiliki N helai baju di rumahnya, yang dinomori dari 1 sampai dengan

N. Baju ke-i memiliki berat sebesar B

i

satuan, daya tahan pakai selama D

i

hari, dan warna

yang dinyatakan dengan sebuah bilangan W

i

. Tentu saja, bilangan yang berbeda menyatakan

warna yang berbeda.

Koper Pak Dengklek hanya dapat memuat baju-baju dengan total berat maksimum sebesar P

satuan. Ia ingin agar dapat membawa baju-baju dengan total daya tahan sebesar mungkin,

namun dengan total berat tidak melebihi P. Ia juga sangat memperhatikan penampilan; oleh

karena itu, ia ingin agar terdapat setidaknya Q warna berbeda pada baju-baju yang

dibawanya.

Tentukan total daya tahan baju-baju terbesar yang dapat dibawa Pak Dengklek dan memenuhi

syarat-syarat tersebut.

Format Masukan

Baris pertama berisi string "Subsoal X" dengan X menyatakan nomor subsoal.

Baris kedua berisi tiga buah bilangan bulat N, P, dan Q. N baris berikutnya masing-masing

berisi tiga buah bilangan bulat B

i

, D

i

, dan W

i

.

Format Keluaran

Sebuah baris berisi sebuah bilangan bulat yang menyatakan total daya tahan terbesar yang

mungkin. Apabila syarat-syarat tersebut tidak mungkin terpenuhi, keluarkan sebuah baris

berisi -1.

Contoh Masukan 1

Subsoal 0 5 10 2 2 5 1 3 3 4 4 2 2 3 2 3 4 6 1

Contoh Keluaran 1

14

(36)

9

Contoh Masukan 2

Subsoal 0 5 7 3 2 5 1 3 3 4 4 2 2 3 2 3 4 6 1

Contoh Keluaran 2

-1

Penjelasan

Pada contoh masukan 1, cara terbaik adalah Pak Dengklek membawa baju-baju nomor 1, 2,

dan 5. Dengan demikian, total beratnya adalah 2 + 3 + 4 = 9 (tidak melebihi 10), banyaknya

warna berbeda adalah 2 (warna 1 dan 4), dan total daya tahan adalah 5 + 3 + 6 = 14 hari.

Pembagian Subsoal

Pada semua subsoal, berlaku:

1 ≤ P ≤ 500

1 ≤ B

i

≤ 100

1 ≤ D

i

≤ 100

Subsoal 1 (9 poin)

Hanya terdapat sebuah kasus uji, yang dapat diunduh

di sini

.

Subsoal 2 (9 poin)

Hanya terdapat sebuah kasus uji, yang dapat diunduh

di sini

.

Subsoal 3 (11 poin)

1 ≤ N ≤ 16

Untuk setiap i, W

i

= i

Q = 0

Subsoal 4 (17 poin)

1 ≤ N ≤ 100

Untuk setiap i, W

i

= i

Q = 0

(37)

10

Subsoal 5 (23 poin)

1 ≤ N ≤ 100

Untuk setiap i, W

i

= i

0 ≤ Q ≤ N

Subsoal 6 (31 poin)

1 ≤ N ≤ 100

1 ≤ W

i

≤ N

0 ≤ Q ≤ N

(38)

11

Pabrik Kue

Batas Waktu 3 detik

Batas Memori 64 MB

Deskripsi

Pak Dengklek memulai usaha produksi kue. Untuk itu, ia membeli 100 mesin pembuat kue.

Setiap mesin memproduksi satu jenis kue yang unik. Karena keterbatasan tempat, seluruh

mesin disimpan pada sebuah gudang. Sedangkan kegiatan produksi dilakukan pada sebuah

ruang di pabrik kecilnya yang hanya bisa menampung maksimum 10 mesin berbeda setiap

harinya.

Setiap pagi Pak Dengklek membuat daftar jenis-jenis kue yang akan diproduksi hari itu agar

pegawainya dapat memindahkan mesin-mesin tersebut dari gudang ke ruang produksi. Setiap

siang, pelanggan-pelanggan datang hendak membeli kue. Setiap jenis kue hanya boleh dibeli

oleh maksimum satu pelanggan. Apabila kue yang diinginkan tidak tersedia, pelanggan akan

pulang dengan tangan kosong.

Karena bukan peramal, Pak Dengklek tidak mengetahui kue-kue mana saja yang akan

dipesan pelanggan pada siang harinya ketika membuat daftar di pagi hari. Tentu saja, Pak

Dengklek ingin agar banyaknya pelanggan yang berhasil membeli kue sebanyak mungkin.

Pak Dengklek menyimpulkan bahwa terdapat pola probabilitas pada pemesanan tiap jenis

kue. Untuk masing-masing jenis kue i, terdapat barisan probabilitas p[i,0], p[i,1], ..., p[i,K

i

-

1]. Barisan ini menyatakan bahwa pada hari ke-t, kue jenis i dipesan dengan probabilitas p[i,

t mod K

i

]. Nilai K

i

ini bisa berbeda antara satu jenis kue dengan jenis kue lainnya. Akan

tetapi, Pak Dengklek tidak mengetahui nilai dari barisan p[i,j] maupun K

i

. Ia hanya

mengetahui bahwa 1 ≤ K

i

≤ 20, dan 0 ≤ p[i,j] ≤ 1 untuk sembarang i dan j.

Petunjuk:Berdasarkan fakta ini, Pak Dengklek menyimpulkan bahwa ketika ia sudah

memiliki cukup banyak data pemesanan yang pernah terjadi, ia dapat memperkirakan pola

pemesanan (p[i,j] dan K

i

). Perkiraan ini cenderung membaik ketika banyaknya data

pemesanan yang ia miliki semakin bertambah, yakni ketika nilai t membesar.

Anda sebagai programmer baru di pabrik Pak Dengklek ditugasi untuk membuat sebuah

program untuk membantu Pak Dengklek membuat daftar mesin yang harus disiapkan setiap

pagi. Upah yang Anda terima ditentukan oleh kinerja program Anda selama T hari

berturut-turut, dan besarnya adalah

dengan a adalah total banyaknya pelanggan yang berhasil membeli kue dan b adalah total

banyak maksimum pelanggan yang mungkin berhasil membeli kue, selama T hari tersebut.

Operator pembagian di sini adalah operator pembagian bilangan riil.

Format Interaksi

(39)

12

Pada awalnya, program Anda harus membaca string "Subsoal X" dengan X menyatakan

nomor subsoal dari kasus uji yang sedang diujikan. Berikutnya program Anda membaca

sebuah baris berisi sebuah bilangan bulat T yang menyatakan banyaknya hari. Kemudian

sebanyak T kali, program Anda berinteraksi dengan program juri. Pada interaksi ke-i,

program Anda:

1. Mengeluarkan sebuah bilangan bulat N (0 ≤ N ≤ 10) ke standar keluaran pada sebuah

baris, yang menyatakan banyaknya mesin kue pada daftar mesin Pak Dengklek.

Kemudian mengeluarkan N bilangan bulat berbeda yang masing-masing menyatakan

nomor jenis kue yang mesinnya akan digunakan di hari itu. Karena Pak Dengklek

hanya memiliki satu mesin untuk memproduksi setiap jenis kue, tidak boleh ada dua

jenis mesin yang sama pada daftar ini.

2. Membaca sebuah bilangan bulat M (0 ≤ M ≤ 100) dari standar masukan pada sebuah

baris, yang menyatakan banyaknya pelanggan yang melakukan pemesanan kue pada

hari ke-i. Kemudian diikuti dengan membaca M buah bilangan bulat berbeda terpisah

baris baru pada sebuah baris, yang masing-masing berupa salah satu bilangan antara 1

hingga 100 yang menyatakan jenis kue yang dibeli pada hari tersebut. Kue-kue

diurutkan secara menaik berdasarkan jenisnya.

Contoh Interaksi

Keluaran Program Peserta

Keluaran Program Juri

Subsoal 0

2

3

1

50

2

2

50

100

2

5

3

2

1

50

(interaksi selesai)

Penjelasan Contoh Kasus Uji

Terdapat 2 kali interaksi.

Pada pagi hari pertama, Pak Dengklek mendaftarkan mesin-mesin untuk memproduksi

kue-kue berjenis 1, 50, dan 2. Pada siang harinya, terdapat 2 pelanggan kue-kue, berjenis 100 dan 50.

Kue berjenis 100 sedang tidak diproduksi sedangkan kue berjenis 50 sedang diproduksi di

hari ini.

Pada pagi hari kedua, Pak Dengklek mendaftarkan mesin-mesin untuk memproduksi kue-kue

berjenis 5 dan 3. Pada siang harinya, terdapat 2 pelanggan kue, berjenis 1 dan 50. Kedua kue

(40)

13

tidak diproduksi di hari ini.

Pada kasus contoh ini, banyak kue yang berhasil dijual ke pelanggan adalah 1. Sedangkan

banyak maksimum kue yang mungkin berhasil dijual adalah 4. Sehingga nilai Anda adalah:

Pembagian Subsoal

Terdapat 25 subsoal.

Pada semua subsoal berlaku:

Hanya terdapat sebuah kasus uji.

Dijamin program juri menentukan kue-kue mana saja yang dibeli pada setiap harinya

tanpa dipengaruhi oleh keluaran program peserta.

T = 1.000

Nilai Anda pada soal ini adalah rata-rata upah yang Anda peroleh pada semua kasus uji

kemudian ditambah setengah lalu dibulatkan ke bawah.

Dengan skema penilaian seperti ini, nilai Anda berada dalam rentang 0..100.

Untuk membantu Anda memahami interaksi, disediakan game yang dapat diakses

di sini

.

Kasus uji yang diberikan pada game ini hanyalah untuk visualisasi dan tidak termasuk dalam

penilaian seperti pada game di soal interaktif sebelumnya.

Catatan

Yang perlu diperhatikan adalah bahwa untuk tipe soal interaktif seperti ini, Anda harus selalu

memberikan perintah "fflush(stdout);" (bagi pengguna C/C++) atau "flush(output);"

(bagi pengguna PASCAL) setiap kali Anda mencetak keluaran (dengan kata lain, setiap kali

ada perintah mencetak keluaran misalnya write, writeln, printf, cout, atau puts, tepat di

bawahnya harus ada perintah fflush/flush).

Sebagai contoh, berikut adalah contoh source code dalam bahasa Pascal yang melakukan

pengisian gudang tanpa memperdulikan pesanan para bebek.

var subsoal: string;

T, M, i, j, pesanan: longint; begin readln(subsoal); readln(T); for i := 1 to T do

(41)

14

begin writeln(3); writeln(1); writeln(50); writeln(2); flush(output); readln(M); for j := 1 to M do readln(pesanan); end; end.

Dan berikut adalah contoh source code dalam bahasa C++.

#include <cstdio> #include <cstring> char subsoal[100]; int nomor; int T, M, i, j, pesanan; int main() {

scanf("%s %d", subsoal, &nomor); scanf("%d", &T); for(i = 1; i <= T; i++) { printf("%d\n%d\n%d\n%d\n", 3, 1, 50, 2); fflush(stdout); scanf("%d", &M); for(j = 1; j <= M; j++) { scanf("%d", &pesanan); } }

(42)

15

return 0; }

Peringatan

Apabila program Anda melakukan salah satu dari hal-hal di bawah ini:

mengeluarkan keluaran tidak sesuai format sehingga tidak dikenali oleh grader, atau

mengeluarkan keluaran tidak sesuai batasan yang tertera di soal

maka program Anda akan dihentikan secara otomatis dan Anda tidak memperoleh nilai pada

kasus uji yang bersangkutan.

(43)

SOLUSI UJIAN

OLIMPIADE SAINS NASIONAL 2013

CALON PESERTA

INTERNATIONAL OLYMPIAD IN INFORMATICS (IOI) 2014

HARI KE-2

Waktu : 5 jam

KEMENTERIAN PENDIDIKAN DAN KEBUDAYAAN

DIREKTORAT JENDERAL PENDIDIKAN MENENGAH

DIREKTORAT PEMBINAAN SEKOLAH MENENGAH ATAS

TAHUN 2013

INFORMATIKA

Hak Cipta

(44)

Solusi Hari-2 - 1

Mengosongkan Matriks

Batas Waktu: 1 detik

Batas Memori: 32 MB

#include <cstdio> #include <cstdlib> #include <cstring> #include <algorithm> using namespace std; int i,j,n,m,ctr,minim,maxim,ans; int a[30][30]; int halo1[300007],halo2[300007],halo3[300007]; char s[1007]; bool sama;

void proses(int com, int x, int y) { int i,j,yow; if (com == 1) { ans++; halo1[ans] = 1; halo2[ans] = x; halo3[ans] = y;

for (i=1 ; i<=n ; i++) a[i][x] = (a[i][x] + y) % 1000000007; } if (com == 2) { ans++; halo1[ans] = 2; halo2[ans] = x; halo3[ans] = y;

for (i=1 ; i<=n ; i++) a[i][x] = (a[i][x] - y) % 1000000007; } if (com == 3) { ans++; halo1[ans] = 3; halo2[ans] = x; halo3[ans] = y; yow = 1;

for (i=1 ; i<=y ; i++) yow = ((long long)yow * 2) % 1000000007; for (j=1 ; j<=m ; j++) a[x][j] = ((long long)a[x][j] * yow) % 1000000007;

}

/* printf("%d %d %d\n",halo1[ans],halo2[ans],halo3[ans]); for (i=1 ; i<=n ; i++) {

for (j=1 ; j<=m ; j++) printf(" %d",a[i][j]); printf("\n"); } // scanf("%d",&yow); */ } int main() { gets(s); scanf("%d%d",&n,&m); for (i=1 ; i<=n ; i++) {

(45)

Solusi Hari-2 - 2

} for (j=1 ; j<=m ; j++) { //printf("KOLOM = %d\n",j); sama = true; minim = a[1][j]; maxim = a[1][j];

for (i=1 ; i<=n ; i++) { if (a[i][j] != a[1][j]) { sama = false; //printf("%d %d\n",i,j); } minim = min(minim,a[i][j]); maxim = max(maxim,a[i][j]); } //printf("%d\n",sama); while (!sama) { while (minim == 0) { proses(1,j,1); minim = a[1][j]; maxim = a[1][j];

for (i=1 ; i<=n ; i++) {

minim = min(minim,a[i][j]); maxim = max(maxim,a[i][j]); }

}

for (i=1 ; i<=n ; i++) { minim = a[1][j]; maxim = a[1][j]; int k; for (k=1 ; k<=n ; k++) { minim = min(minim,a[k][j]); maxim = max(maxim,a[k][j]); } ctr = 0;

while (a[i][j] * (1 << (ctr+1)) <= maxim) ctr++; if (ctr != 0) proses(3,i,ctr);

}

sama = true;

for (i=1 ; i<=n ; i++) if (a[i][j] != a[1][j]) sama = false;

if (!sama) {

minim = a[1][j]; maxim = a[1][j];

for (i=1 ; i<=n ; i++) {

minim = min(minim,a[i][j]); maxim = max(maxim,a[i][j]); } proses(2,j,minim-1); } } if (a[1][j] != 0) proses(2,j,a[1][j]); }

(46)

Solusi Hari-2 - 3

printf("%d\n",ans);

for (i=1 ; i<=ans ; i++) printf("%d %d %d\n",halo1[i],halo2[i],halo3[i]);

(47)

Solusi Hari-2 - 4

Kontes Menari

Batas Waktu: 2 detik

Batas Memori: 32MB

#include <cmath> #include <cstdio> #include <cstdlib> #include <cstring> #include <cassert> #include <climits> #include <vector> #include <string> #include <utility> #include <iostream> #include <algorithm> using namespace std;

#define REP(i,n) for (int i = 0, _n = (int)n; i < _n; i++)

#define FOR(i,a,b) for (int i = (int)a, _b = (int)b; i <= _b; i++) #define RESET(c,v) memset(c, v, sizeof(c))

#define FOREACH(i,c) for (typeof((c).end()) i = (c).begin(); i != (c).end(); ++i)

typedef long long ll;

#define pb push_back #define mp make_pair

const int MAX = 15; int N, R, Y, J; int K[MAX]; char T[MAX][5]; bool used[MAX]; int cur[MAX]; int cnt[100002]; void go(int r) { if (r == R) { int res = 0; int add = 0; REP(i, R) {

int val = K[cur[i]];

if (i && T[cur[i-1]][0] == 'P') val *= 2;

if (i && T[cur[i-1]][0] == 'L') val /= 2;

res += val + add;

if (T[cur[i]][0] == 'Y') add = Y;

}

(48)

Solusi Hari-2 - 5

return; } REP(i, N) if (!used[i]) { cur[r] = i; used[i] = true; go(r+1); used[i] = false; } } int main() { scanf("%*s%*d");

scanf("%d%d%d%d", &N, &R, &Y, &J);

REP(i, N)

scanf("%d%s", &K[i], T[i]);

go(0);

for (int i = 100000; i >= 0; i--) cnt[i] += cnt[i+1]; REP(i, J) { int h; scanf("%d", &h); printf("%d\n", cnt[h+1]); } }

(49)

Solusi Hari-2 - 6

Cuti Liburan

Batas Waktu: 2 detik

Batas Memori: 32MB

#include <cmath> #include <cstdio> #include <cstdlib> #include <cstring> #include <cassert> #include <climits> #include <vector> #include <string> #include <utility> #include <iostream> #include <algorithm> using namespace std;

#define REP(i,n) for (int i = 0, _n = (int)n; i < _n; i++)

#define FOR(i,a,b) for (int i = (int)a, _b = (int)b; i <= _b; i++) #define RESET(c,v) memset(c, v, sizeof(c))

#define FOREACH(i,c) for (typeof((c).end()) i = (c).begin(); i != (c).end(); ++i)

typedef long long ll;

#define pb push_back #define mp make_pair

const int MAX = 100, INF = 999999999;

int N, P, Q;

int B[MAX], D[MAX], W[MAX]; int dp[MAX][505+1][MAX+1][2];

int DP(int i, int berat, int warna, int sudah) {

if (i == N)

return warna >= Q ? 0 : -INF; if (i && W[i] != W[i-1] && sudah) return DP(i, berat, warna, 0);

if (dp[i][berat][warna][sudah] == -1) {

dp[i][berat][warna][sudah] = DP(i+1, berat, warna, sudah); if (berat + B[i] <= P)

dp[i][berat][warna][sudah] = max(dp[i][berat][warna][sudah], D[i] + DP(i+1, berat + B[i], warna + 1 - sudah, 1));

} return dp[i][berat][warna][sudah]; } int main() { scanf("%*s%*d");

scanf("%d%d%d", &N, &P, &Q); REP(i, N)

(50)

Solusi Hari-2 - 7

scanf("%d%d%d", &B[i], &D[i], &W[i]); REP(i, N) REP(j, N-1) if (W[j] > W[j+1]) { swap(B[j], B[j+1]); swap(D[j], D[j+1]); swap(W[j], W[j+1]); } RESET(dp, -1); int res = DP(0, 0, 0, 0);

printf("%d\n", res < 0 ? -1 : res); }

(51)

Solusi Hari-2 - 8

Pabrik Kue

Batas Waktu: 3 detik

Batas Memori: 64MB

#include <cstdio> #include <iostream> #include <algorithm> #include <string> #include <cstring> #include <cstdlib> #include <cmath> #include <memory.h> #include <cassert> #define MP make_pair #define PII pair<int,int>

#define RESET(c,x) memset(c, x, sizeof(c)) using namespace std; char dummy[100]; // algorithm parameters #define CHECKINGPERIOD 10 #define STOPCHECKING 400 #define NCAKE 100 #define NSELCACHE 10 #define MINK 1 #define MAXK 20 #define MAXT 1000 #define F first #define S second #define oo 1000111000

int binary[NCAKE + 5][MAXT + 5]; int freq[NCAKE + 5][MAXT + 5]; PII sorted[NCAKE + 5];

pair <double, int> sortedP[NCAKE + 5]; int T;

int K[NCAKE + 5];

double P[NCAKE + 5][MAXK + 5]; int ctr[MAXT + 5];

template <class T> inline T ABS(T x) { if (x < 0) return -x; return x; } int main() { // read subsoal gets(dummy); scanf("%d", &T); RESET(freq, 0); RESET(binary, 0);

Gambar

Gambar di atas merupakan kondisi kertas yang dibuka dari lipatannya dan dilihat dari sisi  samping ketika permukaan kertas menghadap ke atas dan petak nomor 1 berada di paling kiri

Referensi

Dokumen terkait

Dar hasil penelitian tentang factor sikap Uji korelasi bivariat antara variable Sikap ibu-ibu tentang perawatan bayi ikterus neonatorum dan perilaku ibu-ibu terhadap

Dalam penelitian ini dilakukan analisis beberapa jenis senyawa fitotoksik (asam- asam fenolat dan karboksilat) yang umum dijumpai pada tanah gambut dan perilaku asam-asam

Berdasarkan hasil penelitian menunjukkan analisis hubungan antara pendidikan terakhir ibu dengan pengetahuan tentang kesehatan reproduksi remaja siswa-siswi kelas X dan XI di SMA

Buat selang kepercayaan 90% bagi rataan kecepatan sebenarnya  mobil-mobil yang melaju di jalan raya

 Pencadangan atas pembayaran fee penjualan Migas bagian negara dilakukan apabila terdapat tagihan fee penjualan Migas bagian negara yang seharusnya dibebankan

Hal tersebut dapat diartikan bahwa dengan melakukan pengembangan produk sesuai dengan selera konsumen maka produk tersebut akan lebih diterima oleh konsumen dan akan

Keunggulan laporan standar kualitas interim yaitu perusahaan dapat memantau biaya kualitas sesungguhnya yang telah dikeluarkan, dibandingkan dengan standar biaya kualitas

Tunas Harapan adalah pola inti plasma, dimana perusahaan sebagai inti dan peternak sebagai plasma; (2) Hak dari inti adalah mendapat seluruh hasil produksi