1 条题解
-
0
二、 预备知识点总结
- 循环模拟:
for循环的使用。 - 取模运算:
%用于判断倍数关系。 - 数据类型:
long long用于存储大整数。 - 逻辑控制:
if语句的顺序执行。
三、 启发式教学:草稿纸上的推理过程
教练:“我们把时间轴画出来,每一格代表1分钟。” 假设输入:
S=5, A=2, B=3, K=2, T=6- t=1:
- , 。无事发生。
- 数量:5。
- t=2:
- (繁殖)。数量 。
- 。
- 数量:10。
- t=3:
- 。
- (打击)。数量 。
- 数量:8。
- t=4:
- (繁殖)。数量 。
- 。
- 数量:16。
- t=5:
- 无事发生。
- 数量:16。
- t=6 (关键点!):
- (繁殖)。数量 。
- (打击)。数量 。
- 注意:如果是先打击再繁殖,就是 。结果不一样!题目说先繁殖,所以是 30。
学生总结:一定要按顺序写
if,不能乱。
四、 读题关键词总结
- “先...再...” 决定了代码中
if语句的前后顺序。 - “归为0” / “灭绝” 需要在每次减少后判断是否
<= 0。 - “ 分钟” 循环的终点。
- “数量翻倍” 指数级增长,警惕数据溢出,使用
long long。
五、 标准题解代码 (C++14)
/** * 题目:细菌的繁殖与生存 (Bacterial Reproduction and Survival) * 算法:模拟 (Simulation) * 难度:GESP 4级 / CSP-J T1 */ #include <iostream> using namespace std; int main() { // 1. 养成使用 long long 的习惯,防止细菌指数爆炸溢出 int long long current_bacteria; int A, B, K, T; // 2. 读入数据 if (!(cin >> current_bacteria >> A >> B >> K >> T)) return 0; // 3. 按分钟模拟 for (int t = 1; t <= T; ++t) { // 如果细菌已经灭绝,就不需要再模拟了 if (current_bacteria <= 0) { current_bacteria = 0; break; } // 4. 判断繁殖 (Prior 1) if (t % A == 0) { current_bacteria *= 2; } // 5. 判断打击 (Prior 2) // 注意:这里不能用 else if,因为可能同时发生 if (t % B == 0) { current_bacteria -= K; } // 6. 每次变化后,检查是否灭绝 if (current_bacteria <= 0) { current_bacteria = 0; // 可以选择 break,也可以让循环继续跑(反正 0*2 还是 0) // 为了效率,break 更好 break; } } cout << current_bacteria << endl; return 0; }时间与空间复杂度分析
- 时间复杂度:
- 循环运行 次。内部操作均为 。
- 总复杂度 。因为 ,非常快。
- 空间复杂度:
- 仅使用几个变量,。
六、 数据生成器 (Generator.cpp)
/** * 题目:细菌的繁殖与生存 * 数据生成器 */ #include <iostream> #include <fstream> #include <string> #include <vector> #include <random> #include <ctime> using namespace std; mt19937 rng(time(0)); // 核心解法 long long solve(long long S, int A, int B, int K, int T) { long long cur = S; for(int t=1; t<=T; ++t) { if(cur <= 0) { cur = 0; break; } if(t % A == 0) cur *= 2; if(t % B == 0) cur -= K; if(cur <= 0) { cur = 0; break; } } return cur; } void make_case(int id) { long long S; int A, B, K, T; switch(id) { case 1: // 样例 S = 10; A = 3; B = 4; K = 5; T = 12; break; case 2: // 快速灭绝 S = 10; A = 10; B = 1; K = 10; T = 5; break; case 3: // 只有繁殖 S = 1; A = 1; B = 100; K = 0; T = 30; // 2^30,不溢出 long long break; case 4: // 只有打击 S = 100; A = 100; B = 1; K = 1; T = 50; break; case 5: // 同时发生优先繁殖救命 // T=2: 繁殖x2 -> 20, 打击-15 -> 5. (若先打击则 10-15 < 0 死) S = 10; A = 2; B = 2; K = 15; T = 2; break; case 6: // 随机小数据 S = rng()%20 + 1; A = rng()%5 + 2; B = rng()%5 + 2; K = rng()%10 + 1; T = 20; break; case 7: // 增长较快 S = 100; A = 2; B = 5; K = 10; T = 40; break; case 8: // 刚好不灭绝 S = 10; A = 3; B = 3; K = 7; T = 30; // 每次 x2 -7 -> 20-7=13 -> 26-7=19 (缓慢增长) break; case 9: // 刚好灭绝 S = 10; A = 3; B = 3; K = 20; T = 3; // 3分钟: 20 - 20 = 0 break; case 10: // 较大 T S = 5; A = 2; B = 100; K = 1; T = 60; // 2^30 break; } string in_file = to_string(id) + ".in"; ofstream fout_in(in_file); fout_in << S << " " << A << " " << B << " " << K << " " << T << "\n"; fout_in.close(); string out_file = to_string(id) + ".out"; ofstream fout_out(out_file); fout_out << solve(S, A, B, K, T) << "\n"; fout_out.close(); cout << "Generated Case " << id << endl; } int main() { for(int i=1; i<=10; ++i) make_case(i); return 0; }这道题非常适合 GESP 4 级考生,既练习了基础的循环和条件判断,又引入了数据范围(
long long)的考量,同时背景故事清晰易懂。希望对你的教学有帮助! - 循环模拟:
- 1
信息
- ID
- 19312
- 时间
- 1000ms
- 内存
- 32MiB
- 难度
- 10
- 标签
- (无)
- 递交数
- 1
- 已通过
- 1
- 上传者