ZZNUOJ-2157: 水滴来袭-【干扰阅读-卡模糊精度1e-8的问题】

ZZNUOJ-2157: 水滴来袭

 1 那是一个冷雨霏霏的秋天的下午,当罗辑拿着枪威胁三体文明的时候,如果过了三十秒三体人还没有同他展开谈判,罗辑就会扣动扳机即刻结束自己的生命,随后他身上的核弹控制器就会检测不到他的生命体征进而按照设定引爆数千万枚核弹,
这些排列有序的核弹会以某种原理(具体见原著)向银河系范围公布三体世界的坐标,来自黑暗森林法则的力量就会摧毁掉整个三体星系和太阳系(在太阳系的三体舰队也无法存活)。
2 在通过量子通讯实时得到了这则消息后,作为三体第一舰队的指挥官慌得一批,精通逻辑分析能力的Ta在脑海里迅速展开了一次博弈推理: 3 1、三体世界必须保证无恙,不能冒任何风险。 4 2、三体舰队的水滴此刻距离罗辑Xkm处,光的传播速度为公认值为c=299792458米/秒,水滴可以达到光速的99.98%,可以通过量子通讯技术即刻控制水滴,让水滴“start”(忽略加速时间),前往摧毁罗辑的核弹控制器——罗辑“dying”,
三体世界得以“survive”,三体第一舰队得以抵达地球,获得充分补给和能源“survive”,但地球状况却是“dying”。
5 3、如果水滴在三十秒以后无法及时阻止,那么让水滴保持“static”,三体第一舰队即刻同罗辑谈判,地球和三体世界都得以“survive”;三体第一舰队必然撤退,但注定因为燃料不足,全体舰队成员全部在返航途中“dying”,
地球状况可视为“survive”。
6 指挥官的量子大脑推理的时间忽略不计,即刻迅速行动。 7 输入 8 9 每组样例输入包含两个整数:X和Y。 10 三体舰队的水滴此刻距离地球上罗辑的位置Xkm处,X为整数,1<= X <=10^9. 11 事实上,罗辑其实也慌得一批,自己手里就紧紧握着两个星系的命运;因为他没带手表,所以只好自己在心里默默数数,将数完30个数来作为30秒钟来计算,设他数完30个数的时间为Y秒,Y为整数,5<=Y<=4012 三体第一舰队的指挥官在推理计算时,不知道这个Y值的存在,只按他说的三十秒来计算。 13 14 多实例,不超过10000组数据,处理到EOF结束。 15 16 输出 17 作为三体的一名地球智子观察员,你需要在30秒后向三体总部汇报监测结果,(针对每个样例)简化一下报告内容分别输出五行即可: 18 第一行输出三体第一舰队的状况,格式: "First Fleet : dying/survive" 19 第二行输出罗辑的状况,格式:"LuoJi : dying/survive" 20 第三行输出三体世界的状况,格式:"Home : dying/survive" 21 第四行输出地球的状况,格式: "Earth : dying/survive" 22 第五行输出水滴的状况,格式:"Drop : start/static" 23 第六行输出一个空行,表示分隔行。 24 25 26 样例输入 27 28 1 10 29 5000000 14 30 31 样例输出 32 33 First Fleet : survive 34 LuoJi : dying 35 Home : survive 36 Earth : dying 37 Drop : start 38 39 First Fleet : dying 40 LuoJi : dying 41 Home : dying 42 Earth : dying 43 Drop : start 44 45 46 提示 47 48 如果罗辑开枪的同时水滴摧毁核弹控制器,则视为水滴成功阻止。 49 浮点数之间误差小于等于1e-8,即可认为相等。 50 本题无其他除题意外的特殊情况,本故事剧情纯属虚构。

大致思路:

直接列出真值表:

 

30秒水滴飞不到,直接谈判

30秒可以飞到,但罗辑提前开枪了

30秒可以飞到并赶在他开枪之前

 

dying:(0)/Survive:(1)

dying:(0)/Survive:(1)

dying:(0)/Survive:(1)

First Fleet

0

0

1

LuoJi

1

0

0

home

1

0

1

earth

1

0

0

 

Start:(0)/static(1)

Start:(0)/static(1)

Start:(0)/static(1)

Drop

1

0

0

接下来就是模糊精度处理的问题:

1、如果水滴在30s+1e-9s 的时间赶来,算谁赢?水滴会出动吗? 

 浮点数之间误差小于等于1e-8,即可认为相等。
如果罗辑开枪的同时水滴摧毁核弹控制器,则视为水滴成功阻止。
根据提示里的内容,可以想到30+1e-9确实大于30s但是根据题意是相等的,并且可以在“30秒”的时候成功阻止!
View Code

2、如果水滴在30s+1e-8s 的时间赶来,算谁赢?水滴会出动吗? 

 浮点数之间误差小于等于1e-8,即可认为相等。
如果罗辑开枪的同时水滴摧毁核弹控制器,则视为水滴成功阻止。
根据提示里的内容,可以想到30+1e-9确实大于30s但是根据题意是相等的,并且可以在“30秒”的时候成功阻止!
View Code

3、如果水滴在30s+1e-7s 的时间赶来,算谁赢?水滴会出动吗? 

 浮点数之间误差小于等于1e-8,即可认为相等。
如果罗辑开枪的同时水滴摧毁核弹控制器,则视为水滴成功阻止。
根据提示里的内容,可以想到30+1e-7确实大于30s但是根据题意是不相等的,并且可以在“30秒”的时候是不能成功阻止的!所以只好进行谈判!
View Code

4、如果罗辑在Y秒开枪,水滴可以出动,水滴在Y+1e^-9 的时间赶来,算谁赢?

同理
View Code

5、如果罗辑在Y秒开枪,水滴可以出动,水滴在Y+1e^-8 的时间赶来,算谁赢?

同理
View Code

6、如果罗辑在Y秒开枪,水滴可以出动,水滴在Y+1e^-7 的时间赶来,算谁赢?

同理
View Code

签到题,卡精度,经过不断尝试更改数据范围,发现了一个卡精度卡到 1e^-7 的数据!所以,这个小小的精度WA了所有的人!

double(A) > double(B)的意思是绝对大于的意思,会忽略精度的近似相等的处理要求的!

一旦题目要求精度了,就注意好精度问题,千万不可忽略!建议可以画一个一维的坐标轴范围出来,可以看的更清楚!

题解:

 1 #include<stdio.h>
 2 #include<iostream>
 3 #include<math.h>
 4 using namespace std;
 5 const double eps=1e-7;
 6 #define PI acos(-1.0)
 7 int main(){
 8  //    freopen("input.in","r",stdin);
 9    // freopen("output.out","w",stdout);
10 
11     double X,Y;
12     double vd=299792.458*0.9998;  //水滴速度
13 
14     while(scanf("%lf%lf",&X,&Y)!=EOF){
15 
16         double t1=X/vd;//水滴飞行时间
17         bool ff,fl,fh,fe,fd;
18 
19        if(t1>30.0&&(fabs(t1-30.0)>1e-8)){ //水滴30s飞不到,立即谈判
20           ff=0;
21           fl=1;
22           fh=1;
23           fe=1;
24           fd=1;
25        }
26        else if((t1<30.0||fabs(t1-30.0)<=1e-8 )&&(t1>Y&&fabs(t1-Y)>1e-8)) //水滴起飞,罗辑提前开枪了
27        {
28            ff=0;
29            fl=0;
30            fh=0;
31            fe=0;
32            fd=0;
33        }
34        else{
35            ff=1;
36            fl=0;
37            fh=1;
38            fe=0;
39            fd=0;
40        }
41      //   printf("**Tdrop = %.9lf , Y=%.9lf
",t1,Y);
42 
43        if(ff==0)printf("First Fleet : dying
");
44        else printf("First Fleet : survive
");
45 
46         if(fl==0)printf("LuoJi : dying
");
47        else printf("LuoJi : survive
");
48 
49         if(fh==0)printf("Home : dying
");
50        else printf("Home : survive
");
51 
52         if(fe==0)printf("Earth : dying
");
53        else printf("Earth : survive
");
54 
55         if(fd==0)printf("Drop : start
");
56         else printf("Drop : static
");
57         cout<<endl;
58     }
59 
60     return 0;
61 }
View Code
原文地址:https://www.cnblogs.com/zhazhaacmer/p/9479860.html