Salah satu jebakan terbesar bagi pemula CP adalah bukan algoritma, tetapi parsing input dan format output. Soal CP sering menggunakan format spesifik — “baca t, kemudian untuk setiap test case baca n lalu n elemen” — dan kesalahan kecil seperti lupa newline atau salah tipe data (int vs long long) menyebabkan Wrong Answer yang sulit dilacak. Pada Chapter ini kita akan memetakan tiga pola I/O paling umum di CP, menjelaskan format output standar, dan menulis template siap pakai untuk setiap pola. Tujuan akhirnya: ketika membaca soal baru, kita langsung tahu struktur I/O tanpa perlu eksperimen.
Tiga Pola Input Utama #
| Pola | Format Input | Kapan Muncul |
|---|---|---|
| Single test case | n lalu n elemen | Soal klasik (sum, max, sort) |
| Multiple test case | t lalu t blok, tiap blok punya n elemen | Codeforces standar |
| Edge list / matrix | n m lalu m baris pasangan u v, atau n baris m kolom | Soal graph, grid, matriks |
Mekanisme: Cara Kerja std::cin #
std::cin >> x melakukan tiga hal:
- Skip whitespace — spasi, tab, newline, semuanya dilewati.
- Parse sesuai tipe — integer, float, string non-whitespace.
- Sisakan sisa input di buffer untuk pembacaan berikutnya.
Karena cin skip whitespace, kita dapat membaca “5\n3 9 2 7 5” dengan cin >> n; for (i=0;i<n;i++) cin >> a[i]; tanpa peduli apakah elemen dipisah spasi atau newline. Hal ini sangat nyaman tetapi juga berbahaya: kita mungkin tidak menyadari bahwa input sebenarnya terstruktur berbeda dari asumsi.
Kode: Tiga Pola I/O Siap Pakai #
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
// Pola 1: Single test case
// Input: n, kemudian n integer. Output: sum.
long long solve_sum(const std::vector<int>& a) {
long long s = 0;
for (int x : a) s += x;
return s;
}
// Pola 2: Multiple test case
// Input: t, untuk setiap test: n, kemudian n integer.
// Output: untuk setiap test, sum dari n integer.
void solve_multiple() {
int t;
std::cin >> t;
while (t--) {
int n;
std::cin >> n;
std::vector<int> a(n);
for (int i = 0; i < n; ++i) std::cin >> a[i];
std::cout << solve_sum(a) << '\n';
}
}
// Pola 3: Baca pasangan (u, v) — edge list
void solve_edges() {
int n, m;
std::cin >> n >> m;
std::vector<std::pair<int,int>> edges(m);
for (int i = 0; i < m; ++i) {
std::cin >> edges[i].first >> edges[i].second;
}
std::cout << "n=" << n << " m=" << m << " edges:\n";
for (auto& [u, v] : edges) {
std::cout << " " << u << " - " << v << '\n';
}
}
int main() {
// Demo Pola 1 dengan input internal
std::vector<int> demo = {1, 2, 3, 4, 5};
std::cout << "=== Pola 1: Single case ===\n";
std::cout << "sum(";
for (size_t i = 0; i < demo.size(); ++i) {
std::cout << demo[i];
if (i + 1 < demo.size()) std::cout << ',';
}
std::cout << ") = " << solve_sum(demo) << "\n\n";
std::cout << "=== Pola 2: Multiple test case (simulasi) ===\n";
std::cout << "Format input tipikal:\n";
std::cout << " t (jumlah test case)\n";
std::cout << " n1 (jumlah elemen test 1)\n";
std::cout << " a1 a2 ... an1\n";
std::cout << " n2\n";
std::cout << " a1 a2 ... an2\n";
std::cout << " ...\n\n";
std::cout << "Output:\n";
std::cout << " sum1\n";
std::cout << " sum2\n";
std::cout << " ...\n\n";
std::cout << "=== Pola 3: Edge list (graph) ===\n";
std::cout << "Format input tipikal:\n";
std::cout << " n m (n node, m edge)\n";
std::cout << " u1 v1 (edge 1)\n";
std::cout << " u2 v2\n";
std::cout << " ...\n\n";
std::cout << "=== Format Output Umum ===\n";
std::cout << "Tipe | Contoh\n";
std::cout << "--------------------|-----------------------------------\n";
std::cout << "Single integer | 42\n";
std::cout << "Multiple per baris | 1 2 3 (dipisah spasi)\n";
std::cout << "Array satu per baris| a[0]\\na[1]\\n...\n";
std::cout << "YES/NO | YES\n";
std::cout << "Pair/tuple | (1, 2)\n";
std::cout << "Floating point | 3.14159265358979 (sesuai presisi)\n";
return 0;
}Output yang Dihasilkan:
=== Pola 1: Single case ===
sum(1,2,3,4,5) = 15
=== Pola 2: Multiple test case (simulasi) ===
Format input tipikal:
t (jumlah test case)
n1 (jumlah elemen test 1)
a1 a2 ... an1
n2
a1 a2 ... an2
...
Output:
sum1
sum2
...
=== Pola 3: Edge list (graph) ===
Format input tipikal:
n m (n node, m edge)
u1 v1 (edge 1)
u2 v2
...
=== Format Output Umum ===
Tipe | Contoh
--------------------|-----------------------------------
Single integer | 42
Multiple per baris | 1 2 3 (dipisah spasi)
Array satu per baris| a[0]\na[1]\n...
YES/NO | YES
Pair/tuple | (1, 2)
Floating point | 3.14159265358979 (sesuai presisi)Bedah Kode Baris-per-Baris #
std::cin >> n;: baca integer pertama.cinotomatis skip whitespace sebelumnya.while (t--): pola idiomatik untuk “ulangitkali”.t--post-decrement — saatt = 0, kondisi false, loop berhenti.std::vector<int> a(n); for (int i = 0; i < n; ++i) std::cin >> a[i];: alokasi vektor berukurannlalu baca elemen. Bisa juga pakaia.reserve(n)+push_backtetapi index assignment sedikit lebih cepat.std::vector<std::pair<int,int>> edges(m);: untuk edge list, vektor pasangan adalah struktur paling ringkas.first=u,second=v.for (auto& [u, v] : edges): structured binding C++17 — destrukturisasipairke variabeludanv. Lebih readable dariedges[i].first.std::cout << " " << u << " - " << v << '\n';: cetak pasangan dengan format. Untuk output graph problem, format “u - v” atau “u v” tergantung soal.
Format Output Standar #
| Tipe | Format | Contoh |
|---|---|---|
| Single integer | Cetak nilai + newline | 42\n |
| Array spasi | Elemen dipisah spasi, newline akhir | 1 2 3 4 5\n |
| Array newline | Satu elemen per baris | 1\n2\n3\n4\n5\n |
| YES/NO | Kapital, newline akhir | YES\n atau NO\n |
| Float presisi | setprecision(n) | 3.14159265358979\n |
| Pair/tuple | (a, b) atau a b | (1, 2)\n |
Untuk float dengan presisi tinggi:
#include <iomanip>
std::cout << std::fixed << std::setprecision(10) << ans << '\n';Memilih Tipe Data dari Constraint #
| Constraint Nilai | Tipe yang Aman |
|---|---|
| ` | a[i] |
| ` | a[i] |
n ≤ 10^5, sum bisa besar | long long untuk akumulator |
Hasil kombinasi a[i] * b[i] | Cast ke long long sebelum * |
0 ≤ a[i] ≤ 10^9 dan modulo 10^9+7 | long long untuk operasi antara |
Ringkasan #
- Tiga pola I/O utama: single test case, multiple test case (
tdi awal), edge list / matrix. std::cin >> xotomatis skip whitespace — fleksibel tetapi perlu hati-hati dengangetline.- Format output bervariasi: integer tunggal, array spasi/newline, YES/NO, float presisi.
- Pilih tipe data dari constraint:
intuntuk|v| ≤ 10^9,long longuntuk sum atau|v| ≤ 10^18. - Selalu cetak newline di akhir output — beberapa judge ketat.
- Uji dengan sample input sebelum submit untuk verifikasi format.