Codeforces 237 div2 B. Marathon(关于精度损失的教训)
题目链接:http://codeforces.com/contest/404/problem/B?csrf_token=6292hf3e1h4g5e0d16a996ge6bgcg7g2
解题报告:一个正方形的跑道,边长是a,然后教练给运动员一个规定,每跑d米就额外补充一次饮料,然后输入一个n,表示一共将补充n次,比赛的出发点是(0,0),
也就是左下角的那个点,然后让你求出每次补充饮料的坐标。
本来看起来应该挺简单的一个模拟题,结果没想到一波三折,哎,技术问题啊。首先要注意的就是它规定的是精确到小数点后的四位,所以我在处理的时候,先把输入
全部乘以10000然后转化成整数来处理,这样就可以把小数点后四位以下都忽略掉,然后在输出的时候再转化一下就可以了,这样的想法是对的,但是我首先就犯了一个错误就是这题本来规定的数据范围是10^5,但是我做了乘10000处理,所以数据范围就到了10^9级别,所以int显然是不够的,一开始是这样错的,然后发现了又改过来了,
但是没想到改过来了还是错的,没办法,只好去看测试数据了,结果发现我的第7组测试数据的第6个数比正确的结果大了1,然后果断把那组数据在我本地测试了一下,
结果很纠结,97591.0354 一转化,就像见鬼了一样,转化整数后就成了975910353,怪不得会有个1的差距了,然后我左改又改,就像见鬼了一样,就是有个1的损失,
这时候我才意识到精度损失了,可是怎么解决呢,想起来以前用过一种+0.000001来防止精度损失的办法,果然改过之后就AC 了,哎,虽然这题没A ,但通过这次的教训,我希望可以记住下次碰到这种精度要求较高的题时切记要注意精度的问题了。哦,对了,还有一个,CF规定一定要用__int64,不能出现long long 以及类似的类型。
1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 using namespace std; 6 typedef __int64 INT; 7 8 int main() 9 { 10 double c,e; 11 INT n; 12 while(scanf("%lf%lf",&c,&e)!=EOF) 13 { 14 scanf("%I64d",&n); 15 c *= 10000.0; 16 e *= 10000.0; 17 c += 0.000001; 18 e += 0.000001; 19 INT a = (INT)c; 20 INT d = (INT)e; 21 for(int i = 1;i <= n;++i) 22 { 23 INT race = i * d; 24 race %= (4*a); 25 double x,y; 26 if(race >= 0 && race <= a) 27 { 28 x = (double)race / 10000.0; 29 y = 0; 30 } 31 else if(race > a && race <= 2*a) 32 { 33 race -= a; 34 x = (double)a / 10000.0; 35 y = (double)race / 10000.0; 36 } 37 else if(race > 2*a && race <= 3*a) 38 { 39 race -= (2*a); 40 race = a - race; 41 x = (double)race / 10000.0; 42 y = (double)a / 10000.0; 43 } 44 else if(race > 3*a && race <4*a) 45 { 46 race -= (3*a); 47 race = a - race; 48 x = 0; 49 y = (double)race / 10000.0; 50 } 51 printf("%.10lf %.10lf\n",x,y); 52 } 53 54 } 55 return 0; 56 }