Monster 题解
原网址:来自QZEZOJ
附原题:
题目描述
Teacher Mai has a kingdom. A monster has invaded this kingdom, and Teacher Mai wants to kill it.
Monster initially has h HP. And it will die if HP is less than 1.
Teacher Mai and monster take turns to do their action. In one round, Teacher Mai can attack the monster so that the HP of the monster will be reduced by a. At the end of this round, the HP of monster will be increased by b.
After k consecutive round’s attack, Teacher Mai must take a rest in this round. However, he can also choose to take a rest in any round.
Output “YES” if Teacher Mai can kill this monster, else output “NO”.
翻译:你要打一只h点血的怪物,每回合你攻击会造成a点伤害,回合结束后怪物会回b点血,你每攻击k回合需要休息一次,该回合不能造成伤害。怪物血量降到1以下就会死亡,问最后能否打死怪物。
输入
There are multiple test cases, terminated by a line “0 0 0 0”.
For each test case, the first line contains four integers h,a,b,k(1<=h,a,b,k <=10^9).
输出
For each case, output “Case #k: ” first, where k is the case number counting from 1. Then output “YES” if Teacher Mai can kill this monster, else output “NO”.
样例输入
5 3 2 2
0 0 0 0
样例输出
Case #1: NO
提示
注意是多组数据(while(~scanf()))
题解
先来看一看0.1版代码:
#include<cstdio> using namespace std; int a,b,h,k,i,flag; int main(){ i=1; while(1){ scanf("%d%d%d%d",&h,&a,&b,&k); if(a==0&&b==0&&h==0&&k==0) break; flag=0; if(h<a) flag=1; else if(h+b*k-a*k<1) flag=1; else if(b*(k+1)<a*k) flag=1; else flag=0; if(flag==0) printf("Case #%d: NO\n",i); else printf("Case #%d: YES \n",i); i++; } return 0; }
代码解释:可以有三种情况:
1.一刀带走(h<=a)
2.在k个回合之内带走
3.在k+1个回合的血量小于最初的h (b(k+1)<ak)
**不要急着抄代码 先来看结果:
没错,这就是叫你们不要抄的原因,因为这是WA代码
我进行了一下调试,为三种原因都做了一个样例:
1 5 100 100
10 6 5 5
10 2 1 4
0 0 0 0
原应输出:
Case #1: YES
Case #2: YES
Case #3: YES
结果:
Case #1: YES
Case #2: NO
Case #3: YES
这已经看出问题了。
第二行,原因输出YES但是,输出的是NO,Why?
既然是模拟,那就直接模拟吧,退出0.2版代码(未完待续)
#include<cstdio> using namespace std; int a,b,h,k,i; bool check(){ if(h<a) return true; int sum=h; for(int i=1;i<=k;i++){ sum-=a; if(sum<1) return true; sum+=b; } if(a*k>b*(k+1)) return true; return false; } int main(){ i=1; while(1){ scanf("%d%d%d%d",&h,&a,&b,&k); if(a==0&&b==0&&h==0&&k==0) break; if(check()) printf("Case #%d: YES\n",i); else printf("Case #%d: NO\n",i); i++; } return 0; }
真的是模拟哦~~~
然而,请看测评结果:
TLE
然后,我做了一个极限数据:(第一行重复100次,自己复制)
999999999 2 1 10000000000
0 0 0 0
然后,运行了1.8秒,证明,不能傻傻的用暴力方法
言归正传,其实是一道小学题——蜗牛爬井
当怪物回血的时候,如果血量小于1,其实就不能回了,就OVER了;而蜗牛也是这样,只要是爬到镜头,第二天就不会下落了。
这样就可以做出一个表达式:
h-a<=(a-b)*(k -1 )
注意这个等于号,还有-1,这个就是重点
最后,其实,模拟的精髓——
细节
最后终于AC了
看侧评:
最后是AC代码:(因版权原因,不能展示全部代码)
#include<cstdio> using namespace std; long long a,b,h,k; int i; bool check(){ //(因版权原因,此段代码不能展示) } int main(){ i=1; while(1){ scanf("%d %d %d %d",&h,&a,&b,&k); if(a==0&&b==0&&h==0&&k==0) break; if(check()) printf("Case #%d: YES\n",i); else printf("Case #%d: NO\n",i); i++; } return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具