Berikut adalah ulasan babak penyisihan BNPCHS 2015 yang baru saja berlalu. Ulasan ini ditulis oleh Vincentius Madya Putra yang juga dimuat di blog-nya.
Pada tanggal 2 Agustus 2015, teman-teman dari SMA seluruh Indonesia baru saja melaksanakan babak penyisihan BNPCHS 2015 secara online. Total ada 6 soal dengan tingkat kesulitan yang cukup mudah.
Yang pertama kali mencapai skor penuh adalah peserta dengan username sergioveri dari SMA Intan Permata Hati dengan last accepted submission pada menit ke 24 untuk soal F. Untuk scoreboard penuh dapat dilihat pada tautan berikut
Berikut adalah pembahasan singkat dari soal-soal babak penyisihan.
Problem A - Ini Ibu Budi
Author: Suhendry Effendy
Ini merupakan soal paling mudah pada babak penyisihan. Diberikan input berupa 2 buah bilangan bulat, A dan B. Tugas kita adalah menjumlahkan A sebanyak B kali; dengan kata lain, hitung A * B (A dikali B).
Sebagian besar, peserta tidak memperhatikan format output yang ditentukan soal. Contohnya, apabila input yang diberikan adalah 10 20 (outputnya 200), beberapa kesalahan output yang bisa ditemui dari program peserta, antara lain:
- 200 (salah, karena tidak ada keluaran 'Kasus #X: ')
- KASUS #1: 200 (salah, karena 'KASUS' seharusnya 'Kasus')
- Kasus #1:200 (salah, karena setelah ':' harus diberikan tepat satu spasi)
Tahun ini tidak ada yang mengeluarkan output tambahan yang tidak diminta soal (ct: "Masukan Input: ", "Input: ", dan lainnya). Hal ini menunjukan bahwa sebagian besar para peserta sudah mengerti cara mengambil input pada kontes competitive programming, meskipun banyak yang masih kurang teliti dalam menangani output.
Solusi C++ | |
Solusi Pascal | |
Problem B - Penggemar Berat
Author: Vincentius Madya
Terdapat 2 kondisi tombol. Yang pertama adalah CINTA, yang kedua adalah TIDAK CINTA; jika status tombol sedang berada pada kondisi CINTA, maka status tersebut akan berubah menjadi TIDAK CINTA dengan satu penekanan, begitu juga sebaliknya. Dengan demikian, kita hanya perlu memeriksa apakah banyak penenakan tombol yang dilakukan Sandi adalah ganjil atau genap. Jika ganjil maka statusnya adalah CINTA, jika genap maka statusnya TIDAK CINTA.
Beberapa peserta terbalik dalam menganalisis ganjil-genap tersebut. Hal ini seharusnya bisa langsung diketahui jika peserta menguji programnya dengan contoh input-output yang diberikan di soal. Selain itu, beberapa peserta juga masih melakukan kesalahan ketika menuliskan output 'CINTA' atau 'TIDAK CINTA' dengan huruf kecil (atau hanya huruf pertama yang kapital).
Solusi C++ | |
Solusi Pascal | |
Problem C - Deduksi Peringkat
Author: Gilbert Wonowidjojo
Kita hanya perlu menghitung ada berapa orang yang memiliki nilai lebih besar dari Tedy, dan itulah jawabannya.
Solusi beberapa peserta terlihat berlebihan dengan menggunakan sorting terlebih dahulu (catatan: metode di atas tidak perlu sorting sama sekali). Beberapa peserta (cukup banyak) juga melakukan kesalahan dengan tidak menginisialisasi variable output. Contohnya, ketika metode yang digunakan adalah dengan mengurutkan data secara menurun, kemudian mencari index terkecil di mana P'i lebih kecil atau sama dengan M, maka itulah output yang dikeluarkan. Metode ini tidak akan mengeluarkan output, atau output yang dikeluarkan adalah 0, jika M adalah data yang paling kecil (tidak ada satupun di antara P yang ≤ M).
Solusi C++ | |
Solusi Pascal | |
Problem D - Kacamata Anti-Akik
Author: Gilbert Wonowidjojo
Pada soal ini, kita harus melakukan implementasi yang diminta soal. Salah satu cara implementasinya adalah, cari bagian kiri batu dan bagian kanan batu yang terhubung, anggap L untuk index kiri, dan R untuk index kanan, selama L < R, ubah S[L++] = S[R--] = '.'. Lakukan terus selama masih ada 2 batu yang bersebelahan. Banyak cara untuk mengimplementasi solusi, peserta hanya perlu berhati hati dalam mengimplementasikannya.
Solusi C++ | |
Solusi Pascal | |
Problem E - Roda Gigi
Author: Vincentius Madya
Roda gigi hanya bisa bekerja jika tidak ada roda gigi di sebelah kanan atau kirinya yang arah putarannya sama. Dengan demikian, kondisi roda gigi yang valid hanya ada 2:
- LRLRLRLRLRLR...
- RLRLRLRLRLRL...
Dengan demikian, kita hanya perlu mengecek ada berapa karakter yang berbeda dari dua kondisi tersebut, output yang paling kecil.
Banyak peserta yang memahami cara pengecekan di atas. Namun beberapa peserta hanya berpatokan pada arah putaran roda gigi pertama. Mereka lupa bahwa roda gigi pertama juga bisa kita ubah putarannya. Contoh, 'LLRLRLR', jawaban peserta (yang salah) akan mengeluarkan 6 yang membuat roda gigi menjadi 'LRLRLRL', padahal solusi optimalnya adalah mengubah roda gigi (hanya 1) yang paling depan menjadi 'R' sehingga menjadi 'RLRLRLR'.
Solusi C++ | |
Solusi Pascal | |
Problem F - ROKET-1
Author: Vincentius Madya
Di soal ini, kita perlu melakukan op perkalian/pangkat dengan modulo. Kita hanya perlu mengimplementasikan teori yang diberikan di soal ke dalam program kita. Untuk setiap A * B, ubah menjadi ((A mod M) * (B mod M)) mod M.
Beberapa masalah yang dihadapi peserta saat menjawab soal ini adalah test data 0 1. Banyak peserta yang mencetak 1, sedangkan jawaban yang sebenarnya adalah 0. Sebagian besar disebabkan karena mereka tidak memodulo hasil akhir, sehingga ketika pangkatnya 0, tidak ada operasi modulo yang dipanggil sehingga sebagian peserta mencetak variabel awal yang bernilai 1.
Solusi C++ | |
Solusi Pascal | |
Selain "tidak memperhatikan format output yang diminta soal", beberapa peserta juga menuliskan validasi input pada program mereka. Input yang digunakan juri dijamin sesuai dengan ketentuan soal (sesuai dengan batasan yang tertera), sehingga kita tidak perlu melakukan validasi input.
Peserta yang berhasil lolos ke babak final dapat dilihat pada tautan berikut: here
Selamat untuk para finalis, dan persiapkan diri kalian karena soal final akan lebih menantang dari babak penyisihan :)
Sampai jumpa di babak final. Goodluck and have fun. May the flags be with you :)
-- Vincentius Madya Putra