Bỏ qua

Mô phỏng

Trang này giới thiệu ngắn gọn về các bài toán mô phỏng (simulation).

Giới thiệu

Mô phỏng là dùng máy tính để mô phỏng quá trình được mô tả trong đề bài.

Bài mô phỏng thường có lượng mã lớn, nhiều thao tác và logic phức tạp. Do lượng mã nhiều, dễ phát sinh lỗi khó tìm — trong thi cử sẽ rất tốn thời gian nếu viết sai.

Kỹ thuật

Khi viết mã mô phỏng, tuân theo các đề xuất sau có thể giúp tăng tốc độ làm bài:

  • Trước khi viết code, hãy phác thảo thật kỹ luồng xử lý trên giấy nháp.
  • Trong code, tách các phần thành module, viết hàm, struct hoặc class để dễ quản lý.
  • Với các khái niệm lặp lại, chuẩn hóa (ví dụ: chuyển YY-MM-DD hoặc giờ:phút sang số giây) để tránh nhầm lẫn.
  • Gỡ lỗi theo từng phần; việc module hóa giúp test từng phần độc lập.
  • Khi viết code cần có lộ trình rõ ràng, không nghĩ đến đâu viết tới đó.

Những bước trên cũng có ích cho các loại bài khác.

Ví dụ giải

Climbing Worm

Một con giun (kích thước bỏ qua) ở đáy giếng sâu n inch. Mỗi lần leo lên u inch, nhưng phải nghỉ một lần rồi mới leo tiếp; khi nghỉ, nó trượt xuống d inch. Quá trình lặp lại. Hỏi giun cần ít nhất bao nhiêu lần leo để thoát giếng? Nếu sau lần leo vừa vặn tới miệng giếng thì coi là đã thoát.

Ý tưởng giải

Cứ mô phỏng quá trình giun leo: dùng vòng lặp lặp lại quá trình leo, nếu chiều cao leo được >= n thì dừng.

Tham khảo code
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
#include <iostream>

int main() {
  int n = 0, u = 0, d = 0;
  std::cin >> u >> d >> n;
  int time = 0, dist = 0;
  while (true) {  // 用死循环来枚举
    dist += u;
    time++;
    if (dist >= n) break;  // 满足条件则退出死循环
    dist -= d;
  }
  std::cout << time << '\n';  // 输出得到的结果
  return 0;
}
1
2
3
4
5
6
7
8
9
u, d, n = map(int, input().split())
time = dist = 0
while True:  # 用死循环来枚举
    dist += u
    time += 1
    if dist >= n:  # 满足条件则退出死循环
        break
    dist -= d
print(time)  # 输出得到的结果
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        int n = input.nextInt();
        int u = input.nextInt();
        int d = input.nextInt();
        int time = 0, dist = 0;
        while (true) {  // 用死循环来枚举
            dist += u;
            time++;
            if (dist >= n) {
                break;  // 满足条件则退出死循环
            }
            dist -= d;
        }
        System.out.println(time);   // 输出得到的结果
        input.close();
    }
}

Bài tập