Trên CTOJ, mỗi bài toán được chấm bằng các test case — mỗi test gồm một file input và một file output chuẩn. Chương trình của bạn đọc dữ liệu từ stdin (bàn phím) và in kết quả ra stdout (màn hình). Bài viết này giải thích các quy ước về định dạng test trên CTOJ.
Cách hoạt động
- Hệ thống đưa nội dung file input vào stdin của chương trình.
- Chương trình xử lý và in kết quả ra stdout.
- Hệ thống so sánh stdout của bạn với file output chuẩn.
- Nếu khớp → AC (Accepted). Nếu không khớp → WA (Wrong Answer).
Bạn không cần mở file hay ghi file. Chỉ cần đọc từ stdin và in ra stdout.
Đọc dữ liệu (Input)
C++
Dùng scanf hoặc cin:
#include <bits/stdc++.h>
using namespace std;
int main() {
int n;
scanf("%d", &n); // đọc một số nguyên
vector<int> a(n);
for (int i = 0; i < n; i++)
scanf("%d", &a[i]); // đọc n số nguyên
}
Hoặc dùng cin (chậm hơn nếu không tắt sync):
#include <bits/stdc++.h>
using namespace std;
int main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL);
int n;
cin >> n;
vector<int> a(n);
for (int i = 0; i < n; i++)
cin >> a[i];
}
Python
Dùng input() hoặc sys.stdin:
import sys
input = sys.stdin.readline # nhanh hơn input() mặc định
n = int(input())
a = list(map(int, input().split()))
Java
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int[] a = new int[n];
for (int i = 0; i < n; i++)
a[i] = sc.nextInt();
}
}
Dùng BufferedReader sẽ nhanh hơn đáng kể cho input lớn:
import java.io.*;
import java.util.*;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int n = Integer.parseInt(br.readLine().trim());
StringTokenizer st = new StringTokenizer(br.readLine());
int[] a = new int[n];
for (int i = 0; i < n; i++)
a[i] = Integer.parseInt(st.nextToken());
}
}
In kết quả (Output)
C++
printf("%d\n", result); // printf
cout << result << "\n"; // cout (dùng "\n" thay endl để nhanh hơn)
Python
print(result)
Java
System.out.println(result);
Các định dạng input phổ biến
Một dòng nhiều số
5 3 10
→ Đọc: scanf("%d %d %d", &a, &b, &c) hoặc a, b, c = map(int, input().split())
Dòng đầu là số lượng, dòng sau là dãy số
5
1 3 2 5 4
→ Đọc: dòng 1 cho , dòng 2 cho mảng phần tử.
Đồ thị (danh sách cạnh)
5 6
1 2
1 3
2 4
3 4
4 5
3 5
→ Dòng 1: đỉnh, cạnh. dòng tiếp theo, mỗi dòng là một cạnh.
Nhiều test case trong một file
3
4
1 2 3 4
3
5 6 7
2
10 20
→ Dòng 1: số test . Sau đó lần lượt đọc test case.
Ma trận
3 4
1 2 3 4
5 6 7 8
9 10 11 12
→ Dòng 1: hàng, cột. dòng tiếp theo, mỗi dòng số.
Chuỗi
5
abcde
→ Dòng 1: độ dài chuỗi (hoặc không có, tùy bài). Dòng 2: chuỗi.
Các định dạng output phổ biến
Một số duy nhất
42
Nhiều số trên một dòng (cách nhau bởi dấu cách)
1 3 2 5 4
Mỗi số trên một dòng
1
3
2
5
4
YES / NO
YES
⚠️ Chú ý viết hoa/thường đúng theo yêu cầu đề bài. YES ≠ Yes ≠ yes.
Số thực
3.141593
Thường đề yêu cầu sai số tuyệt đối/tương đối . Dùng printf("%.9f\n", x) trong C++ hoặc print(f"{x:.9f}") trong Python.
Nhiều dòng kết quả
Một số bài yêu cầu in nhiều dòng (ví dụ: in ma trận, in đường đi, ...). Mỗi dòng output tương ứng với một phần kết quả.
Lưu ý quan trọng
Khoảng trắng và xuống dòng
- Các số trên cùng dòng cách nhau bởi đúng một dấu cách.
- Mỗi dòng kết thúc bằng ký tự xuống dòng
\n. - Không in thêm dấu cách thừa ở cuối dòng hoặc dòng trống thừa ở cuối output (hệ thống thường bỏ qua khoảng trắng thừa ở cuối, nhưng tốt nhất nên in đúng).
Kiểu dữ liệu
- Nếu → dùng
int(C++/Java). - Nếu → dùng
long long(C++) hoặclong(Java). Python tự xử lý số lớn. - Luôn đọc kỹ ràng buộc để chọn kiểu dữ liệu phù hợp. Tràn số (overflow) là lỗi rất phổ biến.
Tốc độ I/O
Với bài có input lớn ( dòng):
- C++: Dùng
scanf/printfhoặc thêmios_base::sync_with_stdio(false); cin.tie(NULL);nếu dùngcin/cout. - Python: Dùng
sys.stdin.readlinethay choinput(). Dùngsys.stdout.writethay choprint()nếu cần in nhiều dòng. - Java: Dùng
BufferedReader+StringTokenizerthay choScanner.
Ví dụ hoàn chỉnh
Đề bài: Cho số nguyên, tìm tổng của chúng.
Input:
3
1 2 3
Output:
6
Code C++:
#include <bits/stdc++.h>
using namespace std;
int main() {
int n;
scanf("%d", &n);
long long sum = 0;
for (int i = 0; i < n; i++) {
int x;
scanf("%d", &x);
sum += x;
}
printf("%lld\n", sum);
}
Code Python:
import sys
input = sys.stdin.readline
n = int(input())
a = list(map(int, input().split()))
print(sum(a))
Các dạng bài đặc biệt
Bài có nhiều đáp án đúng
Một số bài chấp nhận nhiều đáp án khác nhau (ví dụ: in một hoán vị thỏa điều kiện). Các bài này sử dụng checker đặc biệt — hệ thống không so sánh từng ký tự mà kiểm tra tính đúng đắn của đáp án.
Bài tương tác (Interactive)
Một số bài yêu cầu chương trình hỏi đáp với hệ thống. Chương trình gửi truy vấn qua stdout, nhận phản hồi từ stdin, và lặp lại cho đến khi tìm ra đáp án. Khi làm bài tương tác, cần flush output sau mỗi truy vấn:
- C++:
fflush(stdout)hoặccout << flush - Python:
print(query, flush=True) - Java:
System.out.flush()
Bài gọi hàm (Signature/Function)
Một số bài yêu cầu bạn chỉ viết một hàm thay vì chương trình hoàn chỉnh. Hệ thống sẽ gọi hàm của bạn với các tham số đã cho và kiểm tra giá trị trả về. Bạn không cần đọc input hay in output — chỉ cần cài đặt đúng hàm theo yêu cầu.
Bình luận