kementerian pendidikan dan kebudayaan

advertisement
Hak Cipta
Dilindungi Undang-undang
SOAL UJIAN
OLIMPIADE SAINS NASIONAL 2013
CALON PESERTA
INTERNATIONAL OLYMPIAD IN INFORMATICS (IOI) 2014
HARI KE-1
INFORMATIKA
Waktu : 5 jam
KEMENTERIAN PENDIDIKAN DAN KEBUDAYAAN
DIREKTORAT JENDERAL PENDIDIKAN MENENGAH
DIREKTORAT PEMBINAAN SEKOLAH MENENGAH ATAS
TAHUN 2013
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 T1 T2 T3 ... TM
yakni, sebuah bilangan bulat M diikuti dengan M buah bilangan bulat dipisahkan spasi, yang
berarti Anda memberi tebakan T = {T1, T2, ... TM}, dengan syarat:
 K≤M≤N
 T1 < T2 < ... < TM
Setiap kali program Anda selesai mengeluarkan tebakan, program Anda membaca sebuah
1
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
2
 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 = 2N
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(log2 N) + 1
 S selalu berupa {1, 2, ..., R} dengan R ≤ N
Subsoal 6 (36 poin)
 2 ≤ N ≤ 100
 K=2
 Q = N2
Catatan
 ceil(x) adalah bilangan bulat terkecil yang lebih besar dari atau sama dengan x.
3
 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);
printf("%d", N);
4
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.
5
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 Ti 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 Ai dan Bi 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 Ti, Ai, dan Bi.
Format Keluaran
Keluarkan salah satu barisan yang memenuhi, dalam format
S1 S2 S3 ... SN
dengan Si 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:
 1 ≤ Ti ≤ 1.000
6
 0 ≤ Ai ≤ Bi ≤ N
 Semua nilai Ti 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
7
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!
8
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.
Kemudian cobalah lipat pada bagian di antara petak 4 dan petak 5.
9
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)
 Hanya terdapat sebuah kasus uji, yang dapat diunduh di sini.
10
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
11
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 P1, P2, P3, P4, P5, dan P6.
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 Kemudian
ke Utara
ke Timur
Kemudian
ke Selatan
Kemudian
ke Barat
P1 (atas)
1
5
3
1
5
P2 (bawah)
6
2
4
6
2
P3 (utara)
2
1
1
4
4
P4 (timur)
4
4
5
5
6
P5 (selatan)
5
6
6
3
3
P6 (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 Q1, Q2, Q3, Q4, Q5, dan Q6.
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 P1, P2, P3, P4, P5, dan P6. Baris ketiga berisi 6 buah bilangan bulat dipisahkan
spasi yang secara berturut-turut menyatakan Q1, Q2, Q3, Q4, Q5, dan Q6.
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
12
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 Q1,Q2, Q3, Q4, Q5, dan Q6 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)
 P1 = 2
 P2 = 2
 P3 = 1
 P4 = 1
 P5 = 1
 P6 = 1
Subsoal 4 (24 poin)
 P1 = 2
 P2 = 1
 P3 = 1
 P4 = 1
 P5 = 1
13
 P6 = 1
Subsoal 5 (42 poin)
 Untuk setiap i, 1 ≤ Pi ≤ 6.
 Mungkin ada dua atau lebih muka sisi dengan nomor yang sama.
14
Hak Cipta
Dilindungi Undang-undang
SOLUSI UJIAN
OLIMPIADE SAINS NASIONAL 2013
CALON PESERTA
INTERNATIONAL OLYMPIAD IN INFORMATICS (IOI) 2014
HARI KE-1
INFORMATIKA
Waktu : 5 jam
KEMENTERIAN PENDIDIKAN DAN KEBUDAYAAN
DIREKTORAT JENDERAL PENDIDIKAN MENENGAH
DIREKTORAT PEMBINAAN SEKOLAH MENENGAH ATAS
TAHUN 2013
Tebak Himpunan
Batas Waktu: 1 detik
Batas Memory: 32 MB
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
<iostream>
<cstdio>
<algorithm>
<cmath>
<cstring>
<string>
<queue>
<stack>
<vector>
<utility>
<map>
#define
#define
#define
#define
REP(a,b) for (int a=0; a<b; a++)
FOR(a,b,c) for (int a=b; a<=c; a++)
FORD(a,b,c) for (int a=b; a>=c; a--)
RESET(a,b) memset(a, b, sizeof a)
#define
#define
#define
#define
#define
#define
#define
#define
#define
EPS 1e-9
INF 2123123123
LL long long
F first
S second
MP make_pair
PB push_back
PII pair<int,int>
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){
if (ada[i]) printf(" %d", i+1);
Solusi Hari-1 - 1
}
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;
}
Solusi Hari-1 - 2
}
}
//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;
}
Solusi Hari-1 - 3
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;
Solusi Hari-1 - 4
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;
}
Solusi Hari-1 - 5
Lipat Kertas
Batas Waktu: 0,2 detik
Batas Memory: 32 MB
#include
#include
#include
#include
#include
<cstdio>
<cstdlib>
<stack>
<cassert>
<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
if
if
if
(sub
(sub
(sub
(sub
==
==
==
==
3)
4)
5)
6)
assert(2
assert(2
assert(2
assert(2
<=
<=
<=
<=
n
n
n
n
&&
&&
&&
&&
n
n
n
n
<=
<=
<=
<=
1000);
4);
1000);
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;
Solusi Hari-1 - 6
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]);
}
Solusi Hari-1 - 7
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];
Solusi Hari-1 - 8
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;
}
Solusi Hari-1 - 9
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;
}
Solusi Hari-1 - 10
Hak Cipta
Dilindungi Undang-undang
SOAL UJIAN
OLIMPIADE SAINS NASIONAL 2013
CALON PESERTA
INTERNATIONAL OLYMPIAD IN INFORMATICS (IOI) 2014
HARI KE-2
INFORMATIKA
Waktu : 5 jam
KEMENTERIAN PENDIDIKAN DAN KEBUDAYAAN
DIREKTORAT JENDERAL PENDIDIKAN MENENGAH
DIREKTORAT PEMBINAAN SEKOLAH MENENGAH ATAS
TAHUN 2013
Mengosongkan Matriks
Batas Waktu
1 detik
Batas Memori 32 MB
Deskripsi
Di sela-sela waktu santai sore, Pak Dengklek memberikan sebuah tantangan bagi bebekbebeknya. 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 2k.
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)
4 Mengurangi bilangan pada kolom 1 dengan 2
1
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.
2. Jika operasi tersebut adalah mengurangi semua bilangan pada suatu kolom tertentu
2
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 2k, 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
3
2
1
3
2
3
2
2
1
2
1
2
2
2
2
2
1
1
1
2
1
1
1
1
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
3
Subsoal 5 (28 poin)
 1 ≤ N, M ≤ 20
4
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 Di.
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 berbedabeda untuk ditampilkan, yang masing-masing dilakukan selama 1 menit. Nomor dari gerakan
yang dilakukan pada menit ke-t (untuk 1 ≤ t ≤ R) dinyatakan oleh Gt. Setelah menampilkan
gerakan Gt peserta akan mendapatkan skor Kt yang besarnya dipengaruhi oleh DGt dan
gerakan-gerakan sebelumnya, yang selengkapnya dihitung menurut aturan berikut.
1. Mula-mula, nilai Kt adalah DGt (yakni, nilai dasar keindahan gerakan nomor Gj).
2. a. Jika t > 1 dan gerakan Gt-1 adalah gerakan memukau, maka nilai Kt dikalikan dua.
b. Jika t > 1 dan gerakan Gt-1 adalah gerakan melelahkan, maka nilai Kt dibagi dua
(dibulatkan ke bawah).
3. Jika untuk suatu m < t, gerakan Gm adalah gerakan meyakinkan, maka
nilai Kt 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 Hi. Juri ke-i akan terkesima dengan tarian peserta jika K1 + K2 + ...
+ KR > Hi.
Berikut ini adalah contoh rangkaian gerakan beserta simulasi perhitungan nilai keindahan
dari setiap gerakan tersebut, dengan R = 6.
t DGt Jenis Gerakan Gt Kt
1 10 biasa
2
5
10
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
5
t DGt Jenis Gerakan Gt Kt
K1 + K2 + ... + K6
62
Diberikan daftar gerakan yang dikuasai oleh Kwek, dan juga batas nilai keindahan masingmasing 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 Di dan sebuah karakter Ti dipisahkan oleh spasi, yang
menyatakan nilai keindahan dari gerakan ke-i dan jenis dari gerakan tersebut. Ti 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 Hi 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.
Untuk juri kedua, tidak ada satupun rangkaian gerakan yang dapat membuat juri tersebut
6
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 ≤ Hi ≤ 100.000
 1 ≤ Di ≤ 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
7
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 Bi satuan, daya tahan pakai selama Di hari, dan warna
yang dinyatakan dengan sebuah bilangan Wi. 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 Bi, Di, dan Wi.
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
8
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 ≤ Bi ≤ 100
 1 ≤ Di ≤ 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, Wi = i
 Q=0
Subsoal 4 (17 poin)
 1 ≤ N ≤ 100
 Untuk setiap i, Wi = i
 Q=0
9
Subsoal 5 (23 poin)
 1 ≤ N ≤ 100
 Untuk setiap i, Wi = i
 0≤Q≤N
Subsoal 6 (31 poin)
 1 ≤ N ≤ 100
 1 ≤ Wi ≤ N
 0≤Q≤N
10
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,Ki 1]. Barisan ini menyatakan bahwa pada hari ke-t, kue jenis i dipesan dengan probabilitas p[i,
t mod Ki]. Nilai Ki ini bisa berbeda antara satu jenis kue dengan jenis kue lainnya. Akan
tetapi, Pak Dengklek tidak mengetahui nilai dari barisan p[i,j] maupun Ki. Ia hanya
mengetahui bahwa 1 ≤ Ki ≤ 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 Ki). 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 berturutturut, 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
Soal ini adalah soal interaktif.
11
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 kuekue berjenis 1, 50, dan 2. Pada siang harinya, terdapat 2 pelanggan 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
12
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
13
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);
}
}
14
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.
15
Hak Cipta
Dilindungi Undang-undang
SOLUSI UJIAN
OLIMPIADE SAINS NASIONAL 2013
CALON PESERTA
INTERNATIONAL OLYMPIAD IN INFORMATICS (IOI) 2014
HARI KE-2
INFORMATIKA
Waktu : 5 jam
KEMENTERIAN PENDIDIKAN DAN KEBUDAYAAN
DIREKTORAT JENDERAL PENDIDIKAN MENENGAH
DIREKTORAT PEMBINAAN SEKOLAH MENENGAH ATAS
TAHUN 2013
Mengosongkan Matriks
Batas Waktu: 1 detik
Batas Memori: 32 MB
#include
#include
#include
#include
<cstdio>
<cstdlib>
<cstring>
<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
}
if (com == 2) {
ans++;
halo1[ans] = 2;
halo2[ans] = x;
halo3[ans] = y;
for (i=1 ; i<=n
}
if (com == 3) {
ans++;
halo1[ans] = 3;
halo2[ans] = x;
halo3[ans] = y;
yow = 1;
for (i=1 ; i<=y
for (j=1 ; j<=m
1000000007;
}
; i++) a[i][x] = (a[i][x] + y) % 1000000007;
; i++) a[i][x] = (a[i][x] - y) % 1000000007;
; i++) yow = ((long long)yow * 2) % 1000000007;
; j++) a[x][j] = ((long long)a[x][j] * yow) %
/* 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++) {
for (j=1 ; j<=m ; j++) scanf("%d",&a[i][j]);
Solusi Hari-2 - 1
}
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]);
}
Solusi Hari-2 - 2
printf("%d\n",ans);
for (i=1 ; i<=ans ; i++) printf("%d %d
%d\n",halo1[i],halo2[i],halo3[i]);
}
Solusi Hari-2 - 3
Kontes Menari
Batas Waktu: 2 detik
Batas Memori: 32MB
#include
#include
#include
#include
#include
#include
<cmath>
<cstdio>
<cstdlib>
<cstring>
<cassert>
<climits>
#include
#include
#include
#include
#include
<vector>
<string>
<utility>
<iostream>
<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;
}
cnt[res]++;
Solusi Hari-2 - 4
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]);
}
}
Solusi Hari-2 - 5
Cuti Liburan
Batas Waktu: 2 detik
Batas Memori: 32MB
#include
#include
#include
#include
#include
#include
<cmath>
<cstdio>
<cstdlib>
<cstring>
<cassert>
<climits>
#include
#include
#include
#include
#include
<vector>
<string>
<utility>
<iostream>
<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)
Solusi Hari-2 - 6
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);
}
Solusi Hari-2 - 7
Pabrik Kue
Batas Waktu: 3 detik
Batas Memori: 64MB
#include
#include
#include
#include
#include
#include
#include
#include
#include
<cstdio>
<iostream>
<algorithm>
<string>
<cstring>
<cstdlib>
<cmath>
<memory.h>
<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
#define
#define
#define
NCAKE 100
NSELCACHE 10
MINK 1
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);
Solusi Hari-2 - 8
for (int t1 = 0; t1 < T; t1++) {
if (t1 <= STOPCHECKING) {
// check periods
for (int i = 0; i < NCAKE; i++) {
int mn = oo;
for (int k = MINK; k <= MAXK; k++) {
int fault = 0;
for (int t = k; t < t1; t++) {
if (ABS(freq[i][t] - freq[i][t - k]) == 1) {
fault++;
}
}
if (fault < mn) {
mn = fault;
K[i] = k;
}
}
}
}
//predict P
for (int i = 0; i < NCAKE; i++) {
for (int k = 0; k < K[i]; k++) {
ctr[k] = 0;
P[i][k] = 0;
}
for (int t = 0; t <= t1; t++) {
P[i][t % K[i]] += 1.0 * freq[i][t];
ctr[t % K[i]]++;
}
for (int k = 0; k < K[i]; k++) {
P[i][k] /= ctr[k];
}
}
for (int i = 0; i < NCAKE; i++) {
sortedP[i] = MP(P[i][t1 % K[i]], i);
}
sort(sortedP, sortedP + NCAKE);
reverse(sortedP, sortedP + NCAKE);
printf("%d\n", NSELCACHE);
for (int i = 0; i < NSELCACHE; i++) {
printf("%d\n", sortedP[i].S + 1);
}
fflush(stdout);
// UPDATE BINARY
int nOrders;
scanf("%d", &nOrders);
for (int i = 0; i < nOrders; i++) {
int x;
scanf("%d", &x);
x--;
binary[x][t1] = 1;
}
// Update freq and fr2
for (int i = 0; i < NCAKE; i++) {
if (t1 > 0) {
Solusi Hari-2 - 9
freq[i][t1] = freq[i][t1 - 1];
}
freq[i][t1] += binary[i][t1];
if (t1 >= 1) {
freq[i][t1] -= binary[i][t1 - 1];
}
}
}
/*
for (int i = 0; i < NCAKE; i++) {
printf("[%d|%d] : ", i + 1, K[i]);
for (int t = 0; t < K[i]; t++) {
printf("%.2lf ", P[i][t]);
}
printf("\n");
}
*/
return 0;
}
Solusi Hari-2 - 10
Hak Cipta
Dilindungi Undang-undang
SOAL UJIAN
OLIMPIADE SAINS NASIONAL 2013
CALON PESERTA
INTERNATIONAL OLYMPIAD IN INFORMATICS (IOI) 2014
SESI LATIHAN
INFORMATIKA
Waktu : 5 jam
KEMENTERIAN PENDIDIKAN DAN KEBUDAYAAN
DIREKTORAT JENDERAL PENDIDIKAN MENENGAH
DIREKTORAT PEMBINAAN SEKOLAH MENENGAH ATAS
TAHUN 2013
Menimbang & Mengurutkan
Batas Waktu: 1 detik
Batas Memori: 32 MB
Deskripsi
Pak Dengklek memiliki N ekor bebek yang dikumpulkan di sebuah kandang yang besar.
Bebek-bebek tersebut dinomori 1 sampai dengan N. Uniknya, berat dari bebek-bebek tersebut
berbeda-beda; yakni, tidak ada dua bebek dengan berat yang sama persis. Namun, sampai
saat ini Pak Dengklek tidak tahu berat masing-masing bebeknya.
Ia ingin memisahkan bebek-bebek tersebut ke dalam N buah kandang baru yang dijejerkan
dari kiri ke kanan. Satu kandang berisi satu bebek. Ia juga ingin agar bebek di kandang paling
kiri adalah bebek teringan, bebek di kandang kedua terkiri adalah bebek teringan kedua, dan
seterusnya sampai bebek di kandang paling kanan adalah bebek terberat.
Tentunya, untuk melakukan hal tersebut, Pak Dengklek harus menimbang bebek-bebeknya.
Namun, ia hanya memiliki sebuah timbangan dua lengan. Untuk menggunakan timbangan
tersebut, Pak Dengklek harus meletakkan seekor bebek pada masing-masing lengan.
Kemudian, timbangan tersebut akan memberi tahu bebek pada lengan mana yang lebih
ringan. Karena timbangan tersebut sudah agak usang, Pak Dengklek hanya bisa melakukan
penimbangan paling banyak K kali.
Bantulah Pak Dengklek menimbang bebek-bebeknya sedemikian sehingga ia dapat
menempatkan bebek-bebeknya pada kandang baru yang sesuai.
Format Interaksi
Soal ini adalah soal interaktif.
Pada awalnya, program Anda harus membaca string "Subsoal X" dengan X menyatakan
nomor subsoal dari kasus uji yang sedang diujikan. Berikutnya program Anda dapat
membaca dua buah bilangan bulat N dan K. Kemudian, sebanyak maksimum K kali, Anda
dapat mengeluarkan perintah dalam sebuah baris dengan format:
timbang B1 B2
yang artinya Anda menaruh bebek nomor B1 pada lengan kiri neraca dan bebek
nomor B2 pada lengan kanan neraca. Untuk melakukan perintah ini, harus berlaku 1 ≤ B1,
B2 ≤ N dan B1 ≠ B2. Setelah itu, program Anda dapat membaca sebuah bilangan -1 atau 1.
Bilangan -1 menandakan bahwa bebek B1 lebih ringan daripada bebek B2, sedangkan 1
menandakan sebaliknya.
Anda juga dapat mengeluarkan perintah dalam sebuah baris dengan format:
jawab B1 B2 ... BN
yang artinya Anda sudah mengetahui semua urutan relatif bebek-bebek dan Anda
memutuskan bahwa bebek nomor Bi adalah bebek teringan ke-i. Setelah itu, interaksi akan
otomatis dihentikan. Jika urutan yang Anda tebak memang sesuai dengan urutan bebek yang
sebenarnya, Anda akan dinyatakan benar untuk kasus uji tersebut. Namun jika tebakan Anda
1
tidak sesuai, Anda dinyatakan salah dan tidak akan mendapat nilai untuk subsoal tersebut.
Contoh Interaksi
Keluaran Program Peserta
Umpan Balik Grader
Subsoal 0
3 3
timbang 1 2
1
timbang 2 3
-1
timbang 3 1
1
jawab 2 1 3
(interaksi selesai)
Penjelasan Contoh Interaksi
Pak Dengklek memiliki 3 ekor bebek. Bebek nomor 2 adalah bebek teringan, bebek nomor 1
adalah bebek teringan kedua, dan bebek nomor 3 adalah bebek terberat.
Pembagian Subsoal
Subsoal 1 (15 poin)
 N = 5.
 K = 15.
Subsoal 2 (20 poin)
 N = 7.
 K = 28.
Subsoal 3 (25 poin)
 N = 12.
 K = 56.
Khusus untuk subsoal 1 sampai dengan subsoal 3:
 Hanya terdapat sebuah kasus uji (satu subsoal dinyatakan oleh satu kasus uji), yang
dapat dimainkan di sini.
 Dalam permainan tersebut, banyaknya pertanyaan yang dapat diajukan tidak dibatasi.
 Jika Anda sudah memenangkan permainan untuk subsoal tertentu, Anda dapat
2
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 4 (40 poin)
 1 ≤ N ≤ 100.
 K = 1.000.
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 akan selalu
menjawab konfigurasi "1 2 3" tanpa mempedulikan nilai N dan K yang diberikan.
var subsoal: string;
N, K: longint;
begin
readln(subsoal);
readln(N, K);
writeln('jawab 1 2 3');
flush(output);
end.
Dan berikut adalah contoh source code dalam bahasa C++.
#include <cstdio>
#include <cstring>
char subsoal[100];
int nomor;
int N, K;
int main() {
3
scanf("%s %d", subsoal, &nomor);
scanf("%d %d", &N, &K);
printf("jawab 1 2 3\n");
fflush(stdout);
return 0;
}
Peringatan
Apabila program Anda melakukan salah satu dari hal-hal di bawah ini:
 mengeluarkan perintah tidak sesuai syarat sehingga tidak dikenali oleh grader, atau
 menimbang dengan nomor bebek yang sama di kedua sisi lengan neraca (misal
'timbang 2 2'), atau
 menimbang lebih dari K kali,
maka program Anda akan dihentikan secara otomatis dan Anda tidak memperoleh nilai pada
kasus uji yang bersangkutan.
4
Fractran
Batas Waktu: 1 detik
Batas Memori: 32 MB
Deskripsi
Sebuah model komputasi alternatif bernama Fractran menggunakan representasi bilangan
pecahan untuk menyatakan proses komputasi. Dalam model ini, sebuah program adalah
sebuah barisan berhingga dari bilangan-bilangan pecahan, sedangkan masukan dan keluaran
adalah sebuah bilangan bulat positif. Proses komputasi berjalan sebagai berikut:
1. Pilih bilangan pertama pada program yang jika dikalikan dengan masukan akan
menghasilkan bilangan bulat. Kemudian, ganti masukan dengan bilangan hasil
perkalian tersebut.
2. Ulangi langkah pertama sampai tidak ada bilangan pada program yang jika dikalikan
dengan masukan akan menghasilkan bilangan bulat.
3. Bilangan hasil perkalian terakhir adalah keluaran dari proses komputasi ini.
Sebagai contoh, misalkan kita mempunyai program = (4⁄3, 2⁄5, 1⁄7) dan masukan = 45. Proses
komputasi berjalan sebagai berikut:
 3 (yakni, penyebut dari 4⁄3) membagi 45, maka masukan diganti dengan 45 × 4⁄3 = 60.
 Karena 60 juga habis dibagi 3, maka masukan diganti dengan 60 × 4⁄3 = 80.
 Karena 80 tidak habis dibagi 3, maka kita cek pecahan kedua: 2⁄5. Ternyata 5 membagi
80, sehingga masukan diganti dengan 80 × 2⁄5 = 32.
 Tidak ada pecahan lagi yang bisa dipakai, sehingga komputasi berhenti dengan nilai
keluaran = 32.
Anda diberikan sebuah bilangan bulat N. Buatlah sebuah program dalam model komputasi
Fractran yang akan mengubah masukan N menjadi keluaran M, dengan M merupakan hasil
perkalian dari semua faktor prima N.
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.
Format Keluaran
Baris pertama berisi sebuah bilangan bulat T yang menyatakan banyaknya pecahan yang
menyusun program. T baris berikutnya masing-masing berisi sebuah pecahan yang menyusun
program, terurut dari awal hingga akhir. Pecahan ditulis sebagai pembilang dan penyebut
(masing-masing berupa bilangan bulat) yang dipisahkan oleh garis miring ('/').
Program yang Anda keluarkan harus memenuhi semua syarat berikut:
 1 ≤ T ≤ 1.000
 Selama proses komputasi, bilangan hasil perkalian masukan dan bilangan pecahan
yang memenuhi syarat tidak pernah melebihi 263 – 1.
 Proses komputasi harus berhenti pada suatu saat.
5
Contoh Masukan
Subsoal 0
200
Contoh Keluaran
3
1/4
3/25
5/3
Penjelasan Contoh Kasus Uji
Pada contoh masukan di atas, N = 200. Faktor-faktor prima dari 200 adalah 2 dan 5, sehingga
M = 2 × 5 = 10.
Proses komputasi dengan masukan N = 200 dan keluaran M = 10 berjalan sebagai berikut:
 200 × 1⁄4 = 50
 50 × 3⁄25 = 6
 6 × 5⁄3 = 10
Pembagian Subsoal
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 (24 poin)
 2 ≤ N ≤ 50.
Subsoal 4 (28 poin)
 2 ≤ N ≤ 500.
Subsoal 5 (30 poin)
 2 ≤ N ≤ 109.
6
Tukar-Tukar
Batas Waktu: 2 detik
Batas Memori: 256 MB
Deskripsi
Pak Dengklek memiliki sebuah tabel berukuran M × N, di mana M menyatakan banyaknya
baris dan N menyatakan banyaknya kolom. Baris dinomori dari 1, 2, hingga M, secara
berurutan dari atas ke bawah. Sedangkan kolom dinomori dari 1, 2, hingga N secara
berurutan dari kiri ke kanan. Masing-masing sel dari tabel itu berisi sebuah bilangan bulat
dalam rentang 0 hingga 1.000. Sebanyak maksimum K kali, Anda dapat menukar isi dari dua
sel yang bersisian. Dua buah sel dikatakan bersisian apabila salah satu sel berada di atas,
bawah, kiri, atau kanan sel lain dan kedua sel berdempetan. Bantulah Pak Dengklek
melakukan maksimum K pertukaran tersebut agar total dari semua selisih pasangan sel yang
bersisian seminimum mungkin.
Format Masukan
Baris pertama masukan berisi string "Subsoal X" di mana X menyatakan nomor subsoal.
Baris kedua berisi tiga buah bilangan bulat M, N, dan K yang terpisah oleh spasi. Sebanyak
M baris berikutnya, masing-masing berisi tepat N bilangan bulat terpisah spasi, masingmasing berada di antara 0 hingga 1.000 (inklusif, termasuk 0 dan 1.000).
Format Keluaran
Baris pertama keluaran berisi sebuah bilangan bulat Y yang menyatakan banyaknya
pertukaran. Sebanyak Y baris berikutnya masing-masing berisi empat buah bilangan bulat
terpisah spasi: r1, c1, r2, c2, yang menyatakan penukaran isi dari sel pada baris r1 dan kolom
c1 dengan sel pada baris r2 dan kolom c2. Keluaran dapat memperoleh nilai lebih dari nol
hanya apabila 0 ≤ Y ≤ K, dan masing-masing dari r1, c1, r2, c2 pada masing-masing baris
mewakili dua sel yang benar-benar berada pada tabel dan bersisian.
Penilaian
Program Anda akan diuji dengan 18 buah kasus uji resmi. Masing-masing kasus uji
dibangkitkan secara acak menurut sebuah bilangan umpan (seed) tertentu. Secara sederhana,
sebuah umpan akan menghasilkan sebuah kasus uji tersendiri.
Anda dapat mengunduh program untuk menguji solusi Anda secara offline di sini. Penguji ini
menggunakan pustaka pembangkit bilangan acak semu yang menjadi default di bahasa C++.
Untuk menggunakan penguji ini, pertama-tama letakkan berkas program di satu direktori
yang sama dengan berkas kode sumber solusi Anda. Lalu buka Command Prompt (untuk
Windows) atau Terminal (untuk Linux) dan tuju direktori tersebut (dengan menggunakan
perintah cd). Kemudian, jalankan perintah:
./penguji <umpan> <program>
(Anda mungkin harus menghapus "./" pada Windows.)
7
Di sini, <umpan> adalah bilangan bulat non-negatif sebagai umpan pembangkit bilangan acak
semu, dan <program> adalah perintah untuk menjalankan program solusi Anda (seperti
"./solusi" pada Linux atau "solusi.exe" pada Windows). Contohnya pada Linux:
./penguji 123 ./solusi
Dan pada Windows:
penguji.exe 123 solusi.exe
Setelah itu, Anda dapat melihat nilai Anda untuk kasus uji tersebut pada layar.
Nilai Anda adalah 10.000.000 dikurangi total dari jumlah semua selisih sel-sel bersisian dari
semua kasus uji.
Contoh Masukan
Subsoal 0
3 3 100
1 2 3
4 5 6
7 8 9
Contoh Keluaran
1
2 2 3 2
Penjelasan Contoh Kasus Uji
Nilai untuk kasus uji di atas adalah 9.999.965.
Apabila tidak terjadi pertukaran, nilai yang diperoleh untuk matriks pada contoh masukan
adalah:
10.000.000-(|1-2|+|2-3|+|1-4|+|2-5|+|3-6|+|4-5|+|5-6|+|4-7|+|5-8|+|6-9|+|7-8|+|8-9|)
yang sama dengan 9.999.976. Penulisan |x| menyatakan harga mutlak dari x. Harga mutlak
dari x didefinisikan sebagai x apabila x adalah bilangan positif, atau -x apabila x bukan
bilangan positif.
Sedangkan, hasil pertukaran sel pada baris 2 kolom 2 dengan sel pada baris 3 kolom 2 akan
menghasilkan matriks:
1 2 3
4 8 6
7 5 9
Nilai yang diperoleh adalah:
10.000.000-(|1-2|+|2-3|+|1-4|+|2-8|+|3-6|+|4-8|+|8-6|+|4-7|+|8-5|+|6-9|+|7-5|+|5-9|)
yang sama dengan 9.999.965.
8
Pembagian Subsoal
Untuk semua subsoal, berlaku batasan:
 1 ≤ M ≤ 100.
 1 ≤ N ≤ 100.
 1 ≤ K ≤ 10.000.
Subsoal 1
 Hanya terdapat satu kasus uji, yang dapat diunduh di sini.
 Perhitungan poin yang Anda dapat di subsoal ini adalah dengan menggunakan
formula berikut.
Subsoal 2
 Perhitungan poin yang Anda dapat di subsoal adalah dengan menggunakan formula
berikut.
9
Hak Cipta
Dilindungi Undang-undang
SOLUSI UJIAN
OLIMPIADE SAINS NASIONAL 2013
CALON PESERTA
INTERNATIONAL OLYMPIAD IN INFORMATICS (IOI) 2014
SESI LATIHAN
INFORMATIKA
Waktu : 2,5 jam
KEMENTERIAN PENDIDIKAN DAN KEBUDAYAAN
DIREKTORAT JENDERAL PENDIDIKAN MENENGAH
DIREKTORAT PEMBINAAN SEKOLAH MENENGAH ATAS
TAHUN 2013
Menimbang & Mengurutkan
Batas Waktu: 1 detik,
Batas Memori: 32 MB
#include
#include
#include
#include
#include
#include
#include
<cstdio>
<iostream>
<algorithm>
<vector>
<cstdlib>
<string>
<cstring>
using namespace std;
char line[500];
int N, K;
vector <int> v;
int C[500][500];
bool cmp(int a, int b) {
if (a == b) return false;
if (C[a][b] != 0) return C[a][b] == -1;
printf("timbang %d %d\n", a, b);
fflush(stdout);
int x;
scanf("%d", &x);
if (x == -1) {
C[a][b] = -1;
return true;
}
C[a][b] = 1;
return false;
}
int main() {
gets(line);
scanf("%d%d", &N, &K);
for (int i = 0; i < N; i++) {
v.push_back(i + 1);
}
sort(v.begin(), v.end(), cmp);
/*
for (int i = 0; i < N; i++) {
for (int j = i + 1; j < N; j++) {
if (cmp(v[j], v[i])) swap(v[j], v[i]);
}
}
*/
printf("jawab");
for (int i = 0; i < N; i++) {
printf(" %d", v[i]);
}
printf("\n");
fflush(stdout);
return 0;
}
Solusi Latihan - 1
Tukar-Tukar
Batas Waktu: 2 detik
Batas Memori: 256 MB
// windows largest seed : 70941581
#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<algorithm>
#include<sstream>
#include<string>
#include<string.h>
#include<deque>
#include<vector>
#include<stack>
#include<queue>
#include<math.h>
#include<map>
#include<set>
using namespace std;
typedef long long LL;
typedef pair<int,int> pii;
double PI = acos(-1);
double EPS = 1e-7;
int INF = 1000000000;
int MAXINT = 2147483647;
LL INFLL = 1000000000000000000LL;
LL MAXLL = 9223372036854775807LL;
#define
#define
#define
#define
fi
se
mp
pb
first
second
make_pair
push_back
#define
#define
#define
#define
#define
#define
(a)++)
#define
#define
#define
SIZE(a) (int)a.size()
ALL(a) a.begin(),a.end()
RESET(a,b) memset(a,b,sizeof(a))
FOR(a,b,c) for (int (a)=(b); (a)<=(c); (a)++)
FORD(a,b,c) for (int (a)=(b); (a)>=(c); (a)--)
FORIT(a,b) for (__typeof((b).begin()) a=(b).begin(); a!=(b).end();
MIN(a, b) (a) = min((a), (b))
MAX(a, b) (a) = max((a), (b))
PAUSE system("pause")
#define input(in) freopen(in,"r",stdin)
#define output(out) freopen(out,"w",stdout)
//1
//2
//0
//3
->
->
->
->
down
up
right
left
Solusi Latihan - 2
pii M[8] = {mp(0,1),mp(1,0),mp(-1,0),mp(0,-1),mp(-1,1),mp(-1,-1),mp(1,1),mp(1,1)};
/*\
\
\
\*/
int
int
int
int
int
int
o[110][110];
x[110][110];
r[110][110];
d[110][110];
s[2][110][110];
n,m,k;
bool vs[2][110][110];
bool valid(int p,int q)
{
return (1 <= p && p <= n && 1 <= q && q <= m);
}
int val(int p,int q,int p2,int q2)
{
if (valid(p2,q2)) return abs(x[p2][q2]-x[p][q]);
else return 0;
}
void upd(int a,int b)
{
if (valid(a,b) && b <= m-1)
{
int sum1 = 0,sum2 = 0;
sum1 += val(a,b,a-1,b)+val(a,b,a+1,b)+val(a,b,a,b-1);
sum1 += val(a,b+1,a-1,b+1)+val(a,b+1,a+1,b+1)+val(a,b+1,a,b+2);
sum2 += val(a,b+1,a-1,b)+val(a,b+1,a+1,b)+val(a,b+1,a,b-1);
sum2 += val(a,b,a-1,b+1)+val(a,b,a+1,b+1)+val(a,b,a,b+2);
r[a][b] = sum1-sum2;
}
if (valid(a,b) && a <= n-1)
{
int sum1 = 0,sum2 = 0;
sum1 += val(a,b,a,b-1)+val(a,b,a,b+1)+val(a,b,a-1,b);
sum1 += val(a+1,b,a+1,b-1)+val(a+1,b,a+1,b+1)+val(a+1,b,a+2,b);
sum2 += val(a+1,b,a,b-1)+val(a+1,b,a,b+1)+val(a+1,b,a-1,b);
sum2 += val(a,b,a+1,b-1)+val(a,b,a+1,b+1)+val(a,b,a+2,b);
d[a][b] = sum1-sum2;
}
}
void init()
{
FOR(a,1,n)
{
FOR(b,1,m-1)
{
int sum1 = 0,sum2 = 0;
sum1 += val(a,b,a-1,b)+val(a,b,a+1,b)+val(a,b,a,b-1);
sum1 += val(a,b+1,a-1,b+1)+val(a,b+1,a+1,b+1)+val(a,b+1,a,b+2);
sum2 += val(a,b+1,a-1,b)+val(a,b+1,a+1,b)+val(a,b+1,a,b-1);
sum2 += val(a,b,a-1,b+1)+val(a,b,a+1,b+1)+val(a,b,a,b+2);
r[a][b] = sum1-sum2;
}
Solusi Latihan - 3
}
FOR(a,1,n-1)
{
FOR(b,1,m)
{
int sum1 = 0,sum2 = 0;
sum1 += val(a,b,a,b-1)+val(a,b,a,b+1)+val(a,b,a-1,b);
sum1 += val(a+1,b,a+1,b-1)+val(a+1,b,a+1,b+1)+val(a+1,b,a+2,b);
sum2 += val(a+1,b,a,b-1)+val(a+1,b,a,b+1)+val(a+1,b,a-1,b);
sum2 += val(a,b,a+1,b-1)+val(a,b,a+1,b+1)+val(a,b,a+2,b);
d[a][b] = sum1-sum2;
}
}
}
vector<pair<int,pii > > v[4];
int process = 0;
pii go(int id)
{
RESET(vs,0);
FOR(a,1,n)
{
FOR(b,1,m)
{
x[a][b] = o[a][b];
}
}
int ans = 0;
int idxans = -1;
int maxans = 0;
init();
FOR(a,0,k-1)
{
int maks = -INF;
int maks2 = -INF;
pii res;
pii res2;
int dir = -1;
FOR(i,1,n)
FOR(j,1,m)
{
if (id == 1)
{
if (r[i][j] > maks)
if (r[i][j] != 0 && (!vs[0][i][j]))
{
maks = r[i][j];
res = mp(i,j);
dir = 1;
}
}
else
{
if (r[i][j] >= maks)
if (r[i][j] != 0 && (!vs[0][i][j]))
{
maks = r[i][j];
res = mp(i,j);
dir = 1;
Solusi Latihan - 4
}
}
}
FOR(i,1,n-1)
FOR(j,1,m)
{
if (id == 1)
{
if (d[i][j] > maks)
if (d[i][j] != 0 && (!vs[1][i][j]))
{
maks = d[i][j];
res = mp(i,j);
dir = 2;
}
}
else
{
if (d[i][j] >= maks)
if (d[i][j] != 0 && (!vs[1][i][j]))
{
maks = d[i][j];
res = mp(i,j);
dir = 2;
}
}
}
if (maks == -INF) break;
if (dir == 1)
{
swap(x[res.fi][res.se],x[res.fi][res.se+1]);
upd(res.fi,res.se);
upd(res.fi,res.se+1);
upd(res.fi,res.se+2);
upd(res.fi,res.se-1);
upd(res.fi-1,res.se);
upd(res.fi+1,res.se);
upd(res.fi-1,res.se+1);
upd(res.fi+1,res.se+1);
}
else
{
swap(x[res.fi][res.se],x[res.fi+1][res.se]);
upd(res.fi,res.se);
upd(res.fi+1,res.se);
upd(res.fi+2,res.se);
upd(res.fi-1,res.se);
upd(res.fi,res.se-1);
upd(res.fi,res.se+1);
upd(res.fi+1,res.se-1);
upd(res.fi+1,res.se+1);
}
v[id].pb(mp(dir,res));
vs[dir-1][res.fi][res.se] = 1;
ans += maks;
if (ans > maxans)
{
maxans = ans;
idxans = a;
FOR(a,1,n)
{
Solusi Latihan - 5
FOR(b,1,m)
{
s[id][a][b] = x[a][b];
}
}
}
}
return mp(maxans,idxans);
}
int main()
{
scanf("%d%d%d",&n,&m,&k);
FOR(a,1,n)
{
FOR(b,1,m)
{
scanf("%d",&o[a][b]);
}
}
pii r2 = go(1);
pii r1 = go(0);
process = 2*n*m*k+n*m;
srand(n*m*k);
if (r1.fi > r2.fi)
{
int extra1 = -1;
int extra2 = -1;
int m1 = 0;
int m2 = 0;
if (n > 2)
{
FOR(a,1,n)
{
FOR(b,1,m)
{
x[a][b] = s[0][a][b];
}
}
pair<int,pii> p = mp(-INF,mp(-1,-1));
int co = 0;
while(r1.se+1+extra1+1+2 <= k && process < 500000000)
{
int i = rand()%(n-2)+1;
int j = rand()%m+1;
int sum1 = 0;
int sum2 = 0;
sum1 += val(i,j,i,j-1)+val(i,j,i,j+1)+val(i,j,i-1,j);
sum1 += val(i+2,j,i+2,j1)+val(i+2,j,i+2,j+1)+val(i+2,j,i+3,j);
sum1 += val(i+1,j,i+1,j-1)+val(i+1,j,i+1,j+1);
sum1 += val(i,j,i+1,j) + val(i+1,j,i+2,j);
sum2 += val(i+2,j,i,j-1)+val(i+2,j,i,j+1)+val(i+2,j,i1,j);
sum2 += val(i+1,j,i+2,j1)+val(i+1,j,i+2,j+1)+val(i+1,j,i+3,j);
sum2 += val(i,j,i+1,j-1)+val(i,j,i+1,j+1);
sum2 += val(i+2,j,i,j) + val(i,j,i+1,j);
if (sum1 - sum2 > 0)
Solusi Latihan - 6
{
if (p < mp(sum1-sum2,mp(i,j))) p = mp(sum1sum2,mp(i,j));
co++;
if (co == 20)
{
m1 += p.fi;
int i=p.se.fi,j =p.se.se;
swap(x[i+1][j],x[i+2][j]);
swap(x[i][j],x[i+1][j]);
extra1 += 2;
v[2].pb(mp(2,mp(i+1,j)));
v[2].pb(mp(2,mp(i,j)));
co = 0;
p = mp(-INF,mp(-1,-1));
}
}
process += 1000;
}
}
if (m > 2)
{
FOR(a,1,n)
{
FOR(b,1,m)
{
x[a][b] = s[0][a][b];
}
}
pair<int,pii> p = mp(-INF,mp(-1,-1));
int co = 0;
while(r1.se+1+extra2+1+2 <= k && process < 1000000000)
{
int i = rand()%n+1;
int j = rand()%(m-2)+1;
int sum1 = 0;
int sum2 = 0;
sum1 += val(i,j,i-1,j)+val(i,j,i+1,j)+val(i,j,i,j-1);
sum1 += val(i,j+2,i1,j+2)+val(i,j+2,i+1,j+2)+val(i,j+2,i,j+3);
sum1 += val(i,j+1,i-1,j+1)+val(i,j+1,i+1,j+1);
sum1 += val(i,j,i,j+1) + val(i,j+1,i,j+2);
sum2 += val(i,j+2,i-1,j)+val(i,j+2,i+1,j)+val(i,j+2,i,j-1);
sum2 += val(i,j+1,i1,j+2)+val(i,j+1,i+1,j+2)+val(i,j+1,i,j+3);
sum2 += val(i,j,i-1,j+1)+val(i,j,i+1,j+1);
sum2 += val(i,j+2,i,j) + val(i,j,i,j+1);
if (sum1 - sum2 > 0)
{
if (p < mp(sum1-sum2,mp(i,j))) p = mp(sum1sum2,mp(i,j));
co++;
if (co == 20)
{
m2 += p.fi;
int i=p.se.fi,j =p.se.se;
swap(x[i][j+1],x[i][j+2]);
swap(x[i][j],x[i][j+1]);
extra2 += 2;
v[3].pb(mp(1,mp(i,j+1)));
v[3].pb(mp(1,mp(i,j)));
Solusi Latihan - 7
co = 0;
p = mp(-INF,mp(-1,-1));
}
}
process += 1000;
}
}
if (m1 > m2)
{
printf("%d\n",r1.se+1+extra1+1);
FOR(a,0,r1.se)
{
if (v[0][a].fi == 1) printf("%d %d %d
%d\n",v[0][a].se.fi,v[0][a].se.se,v[0][a].se.fi,v[0][a].se.se+1);
else printf("%d %d %d
%d\n",v[0][a].se.fi,v[0][a].se.se,v[0][a].se.fi+1,v[0][a].se.se);
}
FOR(a,0,extra1)
{
if (v[2][a].fi == 1) printf("%d %d %d
%d\n",v[2][a].se.fi,v[2][a].se.se,v[2][a].se.fi,v[2][a].se.se+1);
else printf("%d %d %d
%d\n",v[2][a].se.fi,v[2][a].se.se,v[2][a].se.fi+1,v[2][a].se.se);
}
}
else
{
printf("%d\n",r1.se+1+extra2+1);
FOR(a,0,r1.se)
{
if (v[0][a].fi == 1) printf("%d %d %d
%d\n",v[0][a].se.fi,v[0][a].se.se,v[0][a].se.fi,v[0][a].se.se+1);
else printf("%d %d %d
%d\n",v[0][a].se.fi,v[0][a].se.se,v[0][a].se.fi+1,v[0][a].se.se);
}
FOR(a,0,extra2)
{
if (v[3][a].fi == 1) printf("%d %d %d
%d\n",v[3][a].se.fi,v[3][a].se.se,v[3][a].se.fi,v[3][a].se.se+1);
else printf("%d %d %d
%d\n",v[3][a].se.fi,v[3][a].se.se,v[3][a].se.fi+1,v[3][a].se.se);
}
}
}
else
{
int extra1 = -1;
int extra2 = -1;
int m1 = 0;
int m2 = 0;
if (n > 2)
{
FOR(a,1,n)
{
FOR(b,1,m)
{
x[a][b] = s[1][a][b];
}
}
Solusi Latihan - 8
pair<int,pii> p = mp(-INF,mp(-1,-1));
int co = 0;
while(r2.se+1+extra1+1+2 <= k && process < 500000000)
{
int i = rand()%(n-2)+1;
int j = rand()%m+1;
int sum1 = 0;
int sum2 = 0;
sum1 += val(i,j,i,j-1)+val(i,j,i,j+1)+val(i,j,i-1,j);
sum1 += val(i+2,j,i+2,j1)+val(i+2,j,i+2,j+1)+val(i+2,j,i+3,j);
sum1 += val(i+1,j,i+1,j-1)+val(i+1,j,i+1,j+1);
sum1 += val(i,j,i+1,j) + val(i+1,j,i+2,j);
sum2 += val(i+2,j,i,j-1)+val(i+2,j,i,j+1)+val(i+2,j,i1,j);
sum2 += val(i+1,j,i+2,j1)+val(i+1,j,i+2,j+1)+val(i+1,j,i+3,j);
sum2 += val(i,j,i+1,j-1)+val(i,j,i+1,j+1);
sum2 += val(i+2,j,i,j) + val(i,j,i+1,j);
if (sum1 - sum2 > 0)
{
if (p < mp(sum1-sum2,mp(i,j))) p = mp(sum1sum2,mp(i,j));
co++;
if (co == 20)
{
m1 += p.fi;
int i=p.se.fi,j =p.se.se;
swap(x[i+1][j],x[i+2][j]);
swap(x[i][j],x[i+1][j]);
extra1 += 2;
v[2].pb(mp(2,mp(i+1,j)));
v[2].pb(mp(2,mp(i,j)));
co = 0;
p = mp(-INF,mp(-1,-1));
}
}
process += 1000;
}
}
if (m > 2)
{
FOR(a,1,n)
{
FOR(b,1,m)
{
x[a][b] = s[1][a][b];
}
}
pair<int,pii> p = mp(-INF,mp(-1,-1));
int co = 0;
while(r2.se+1+extra2+1+2 <= k && process < 1000000000)
{
int i = rand()%n+1;
int j = rand()%(m-2)+1;
int sum1 = 0;
int sum2 = 0;
sum1 += val(i,j,i-1,j)+val(i,j,i+1,j)+val(i,j,i,j-1);
sum1 += val(i,j+2,i1,j+2)+val(i,j+2,i+1,j+2)+val(i,j+2,i,j+3);
sum1 += val(i,j+1,i-1,j+1)+val(i,j+1,i+1,j+1);
Solusi Latihan - 9
sum1 += val(i,j,i,j+1) + val(i,j+1,i,j+2);
sum2 += val(i,j+2,i-1,j)+val(i,j+2,i+1,j)+val(i,j+2,i,j-1);
sum2 += val(i,j+1,i1,j+2)+val(i,j+1,i+1,j+2)+val(i,j+1,i,j+3);
sum2 += val(i,j,i-1,j+1)+val(i,j,i+1,j+1);
sum2 += val(i,j+2,i,j) + val(i,j,i,j+1);
if (sum1 - sum2 > 0)
{
if (p < mp(sum1-sum2,mp(i,j))) p = mp(sum1sum2,mp(i,j));
co++;
if (co == 20)
{
m2 += p.fi;
int i=p.se.fi,j =p.se.se;
swap(x[i][j+1],x[i][j+2]);
swap(x[i][j],x[i][j+1]);
extra2 += 2;
v[3].pb(mp(1,mp(i,j+1)));
v[3].pb(mp(1,mp(i,j)));
co = 0;
p = mp(-INF,mp(-1,-1));
}
}
process += 1000;
}
}
if (m1 > m2)
{
printf("%d\n",r2.se+1+extra1+1);
FOR(a,0,r2.se)
{
if (v[1][a].fi == 1) printf("%d %d %d
%d\n",v[1][a].se.fi,v[1][a].se.se,v[1][a].se.fi,v[1][a].se.se+1);
else printf("%d %d %d
%d\n",v[1][a].se.fi,v[1][a].se.se,v[1][a].se.fi+1,v[1][a].se.se);
}
FOR(a,0,extra1)
{
if (v[2][a].fi == 1) printf("%d %d %d
%d\n",v[2][a].se.fi,v[2][a].se.se,v[2][a].se.fi,v[2][a].se.se+1);
else printf("%d %d %d
%d\n",v[2][a].se.fi,v[2][a].se.se,v[2][a].se.fi+1,v[2][a].se.se);
}
}
else
{
printf("%d\n",r2.se+1+extra2+1);
FOR(a,0,r2.se)
{
if (v[1][a].fi == 1) printf("%d %d %d
%d\n",v[1][a].se.fi,v[1][a].se.se,v[1][a].se.fi,v[1][a].se.se+1);
else printf("%d %d %d
%d\n",v[1][a].se.fi,v[1][a].se.se,v[1][a].se.fi+1,v[1][a].se.se);
}
FOR(a,0,extra2)
{
if (v[3][a].fi == 1) printf("%d %d %d
%d\n",v[3][a].se.fi,v[3][a].se.se,v[3][a].se.fi,v[3][a].se.se+1);
Solusi Latihan - 10
else printf("%d %d %d
%d\n",v[3][a].se.fi,v[3][a].se.se,v[3][a].se.fi+1,v[3][a].se.se);
}
}
}
}
Solusi Latihan - 11
Fractran
Batas Waktu: 1 detik
Batas Memori: 32 MB
#include <cstdio>
#include <cstring>
#include <cassert>
#include
#include
#include
#include
#include
#include
#include
<vector>
<string>
<set>
<map>
<utility>
<iostream>
<algorithm>
using namespace std;
#define REP(i,n) for (int i = 0; i < (int)n; i++)
#define FOR(i, a, b) for (int i = (int)a; i <= (int)b; i++)
#define FOREACH(i,c) for (typeof((c).end()) i = (c).begin(); i !=
(c).end(); ++i)
#define RESET(c,v) memset(c, v, sizeof(c))
#define pb push_back
#define mp make_pair
/* ****************************************************************** */
char line[1024], buf[1024];
int pos, add;
#define begin_line() {gets(line); pos = 0;}
#define end_line() {assert(sscanf(line+pos, "%s", buf) == EOF);}
#define end_file() {assert(scanf("%s", buf) == EOF);}
#define read_int(n) {assert(sscanf(line+pos, "%d%n", &n, &add) != EOF); pos
+= add;}
#define read_long(n) {assert(sscanf(line+pos, "%lld%n", &n, &add) != EOF);
pos += add;}
#define read_string(n) {assert(sscanf(line+pos, "%s%n", n, &add) != EOF);
pos += add;}
#define constraint(n) assert(n)
/* ****************************************************************** */
const int
SUBSOAL = 5,
MAXN = 1000000000;
char subsoal[15]; int X;
int N;
int main()
{
begin_line();
read_string(subsoal);
read_int(X);
Solusi Latihan - 12
constraint(strcmp(subsoal, "Subsoal") == 0);
end_line();
if (X==7)
{
printf("1\n999999999/2\n");
return 0;
}
begin_line();
read_int(N);
constraint(2 <= N && N <= MAXN);
end_line();
// check trailing characters
end_file();
int
int
int
int
i =
ans
x =
n =
2;
= 1;
N;
x;
while (i*i <=
if (n % i
ans =
while
}
i++;
}
n) {
== 0) {
ans * i;
(n % i == 0) n = n / i;
ans = ans * n;
//printf("%d\n",ans);
if (x == ans) {
printf("1\n");
printf("1/1000000009\n");
} else {
printf("2\n");
printf("1000000009/%d\n",x);
printf("%d/1000000009\n",ans);
}
}
Solusi Latihan - 13
Download