原网址:来自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
- [x] 测试点一
- [ ] 测试点二
- [x] 测试点三
这已经看出问题了。
第二行,原因输出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;
}