模拟:把题目翻译成代码¶
什么是模拟?¶
模拟就是题目干什么,你写什么。题目说「每过一分钟转 90 度」,你的代码就让状态转 90 度;题目说「得分超过 11 分且领先 2 分赢一局」,你的代码就原样判断。
没有高深算法,全靠读题仔细 + 翻译忠实。模拟题丢分从来不是因为不会做,而是因为:看漏一句话、边界差一位、格式差一个空格。
模拟题三板斧¶
- 变量起名跟题走:题目叫「得分」就叫
score,别叫x - 分步写注释:把题面逐句变成注释,再逐句填代码
- 手动模拟小数据:写完先拿样例在纸上走一遍程序,对得上再提交
例题:不高兴的津津¶
题目描述 津津每天要上学,回家后妈妈还安排了课外班。如果一天上课总时间超过 8 小时,津津就不高兴,而且越超越不高兴。给出 7 天的安排(学校上课小时数、课外班小时数),求津津最不高兴的是哪一天;如果有并列的,输出最靠前的那天。若天天都不超过 8 小时,输出 0。
输入格式 7 行,每行两个整数 \(a\)、\(b\)(学校、课外班,单位小时)。
输出格式 一个整数(1~7 或 0)。
数据范围 \(0 \le a, b \le 10\)。
样例输入 / 样例输出
思路分析 逐句翻译题面:每天总时长 = 学校 + 课外班;超过 8 才有资格比较;「最不高兴」= 总时长最大;「并列取最靠前」= 严格大于才更新。这就是第 2 章「擂台找最大值」的翻版,多了一个「超过 8 才上擂台」的前提。
参考代码
#include <iostream>
using namespace std;
int main() {
int worstDay = 0; // 0 表示还没有不高兴的日子
int worstTime = 8; // 擂台基线:超过 8 才算不高兴
for (int day = 1; day <= 7; day++) {
int a, b;
cin >> a >> b;
int total = a + b;
if (total > worstTime) { // 严格大于 → 并列时保留更早的天
worstTime = total;
worstDay = day;
}
}
cout << worstDay << endl;
return 0;
}
验证样例:7 天总时长分别是 8 8 9 8 9 4 6——第 3 天 9 小时、第 5 天也是 9,并列取靠前的第 3 天。✅
这就是洛谷 P1085 不高兴的津津,NOIP2004 普及组真题。
模拟的经典变体¶
模拟题的花样全在状态的表示方式上,你已学过的工具对应一批经典题型:
| 状态表示 | 典型题目 |
|---|---|
| 数组标记 | 校门外的树(第 3 章已做) |
| 二维数组棋盘 | 井字棋胜负判断、铺地毯 |
| 计数器 + 循环 | 约瑟夫报数(第 6 章用队列再战) |
| 多变量维护 | 乒乓球比分(11 分制 / 21 分制双规则) |
洛谷 P1042 乒乓球(NOIP2003 真题)是模拟题的标杆练习:读一串 WE 字符表示得分,同时按 11 分制和 21 分制输出每局比分——规则读细,两遍输出,写完拿样例逐字符核对。
动手试一试¶
- 时钟模拟:读入起始时刻(时:分)和经过分钟数 \(t\)(\(t \le 10^9\)),输出最终时刻(注意取模)
- 读入 \(n\) 和 \(n\) 个体温,输出第一次超过 \(37.3\) 的序号;都不超输出
OK - 铺地毯(洛谷 P1003,NOIP2011 提高 T1 但难度不高):平面上依次铺 \(n\) 张矩形地毯,问最上面盖住点 \((x,y)\) 的是第几张
- 挑战 P1042 乒乓球:注意「达到 11 分且领先 2 分」才结束一局,最后一局可能没打完也要输出
下一课:每一步都拿眼前最好的——贪心。