佛系AC法 eps 误差 hdu 6308

在第一场HDU多校里面,我拿到了数据 in out文件

数据给了很多  多到40680组每个时间和状态都去试了一遍

昨天的那个D写的也是 4 8 4 8 这种毫无意义的两组相同的都生成了

生成了你不能说什么 并且果然又两组这样相同的数据 你的程序就崩了

HDU似乎又很喜欢输入数据很多组

或者至少不是很多组 是你把cin换成scanf就能从TLE变成WA的那种 …… 

以HDU多校第一场 为例

Time Zone

 HDU - 6308 

其实完全没什么...   化成分钟 随便搞搞... 

放代码 

#include <iostream>
using namespace std;
int main()
{	int t;
	cin >> t;
	while (t--)
	{	int  a; int b;
		double s;
		char c1, c2, c3, c4;
		scanf("%d %d %c%c%c%c%lf", &a, &b, &c1, &c2, &c3, &c4,&s);
		//scanf("%lf",&s);
		//cout << s << endl;
		int cnt;
		cnt = a * 60 + b;//所有的时间
		double record;
		if (c4 == '-')s = 0-s;
		record = s-(8*1.0);
		
		if (record>=0)cnt += int(record*60+0.1);
		else if (record < 0)cnt += int(record * 60 -0.1);
		//cout << record * 60<<endl;
		//cout << record * 60 -0.1 << endl;
		cnt = (cnt + 1440+1440) % 1440;
		int xx = cnt / 60;
		int aa = xx / 10; int bb = xx % 10; int cc = (cnt - xx * 60) / 10;
		int dd = (cnt - xx * 60) % 10;
		printf("%d%d:%d%d\n", aa, bb, cc, dd);
		/*if (xx <= 9)
			printf("0%d:",&xx);
			//cout << "0" << xx <<":"<< endl;
		else printf("%d:", &xx);//cout << xx << endl;*/
	}
	return 0;
}

但是有个很大的问题 就是精度误差

精度误差本来也没什么   我们最后那几位 用char 和strlen读就可以了

【待补充 做法2】

 

好了我脑子是乱的根本A不了...  不知道自己是在干嘛

以后两点再来吧.. 妈个鸡

**********************************

使用字符串的时候要注意:

1 最开始写char s[20]

2 scanf("%s",s)   不用加& 不用加& 不用加&

3 用的时候 可以int len=strlen(s); 完全可以用

4  字符串之间相互转化  用time1 = (ss[0] - '0');

把它化成..  反正能用..

-'0'真是太棒了

......到时候记得用

反正这个会读了一行的 不会换的什么的

**********************************

经过我的一些夏继尔测试....

 

 

 

 

发现这一组会有问。并且,VS不给跑。编译环境不一样,你要用codeblocs改。

放到codeblocks里,果然不一样。

问题出在二进制读入和转化时的误差。

如0.6换成二进制的时候,因为是*0.2进行转化,所以是0.100100100100...(有循环节)

而显示出来,double读一个7.6就会显示成7.599999999996

当然用的时候double还是四舍五入的,这没什么。

但是,当遇到一些情况之后,比如这个题,先是-8 变成了-0.400000000004

然后,*60变成了-24.00000000240

如果是25+它的话 double是0.99999999999760

double输出当然是四舍五入的1 它不告诉你

int就很傻了,变成了0,误差由此产生了。

这个代码看别人正的+0.1  负的-0.1就可以了

(后面强制成int)

以后不知道能遇到什么....

图片

 

 

 

(应该是936) 因为在数据转换的时候  都是double还能自动舍入  因为double知道double这是0.000000024的误差 int不知道 int直接把后面的都舍去了....

下面kk935 kkk936

这个其实,有了足够的经验就会知道有的数据可能并不是出题者有意为之,但是就是会卡到精度。

和其他相比,于我,acm评测机已经算是很有一说一的公平东西了。

……

此外看了一篇文章: https://blog.csdn.net/major_zhang/article/details/65449685

(以下为转载)*****

【输出陷阱I】

这一节和下一节一样,都是因为题目要求输出浮点数,导致的问题。而且都和四舍五入有关。

说到四舍五入,就再扯一下相关内容,据我所知有三种常见的方法:

1. printf(“%.3lf”, a);  //保留a的三位小数,按照第四位四舍五入

2. (int)a;  //将a靠进0取整

3. ceil(a); floor(a);   //顾名思义,向上取证、向下取整。需要注意的是,这两个函数都返回double,而非int

其中第一种很常见于输出(nonsense…)。

现在考虑一种情况,题目要求输出保留两位小数。有个case的正确答案的精确值是0.005,按理应该输出0.01,但你的结果可能是0.005000000001(恭喜),也有可能是0.004999999999(悲剧),如果按照printf(“%.2lf”, a)输出,那你的遭遇将和括号里的字相同。

解决办法是,如果a为正,则输出a+eps, 否则输出a-eps

典型案例: POJ2826

【输出陷阱II】

ICPC题目输出有个不成文的规定(有时也成文),不要输出: -0.000

那我们首先要弄清,什么时候按printf(“%.3lf\n”, a)输出会出现这个结果。

直接给出结果好了:a∈(-0.000499999……, -0.000……1)

所以,如果你发现a落在这个范围内,请直接输出0.000。更保险的做法是用sprintf直接判断输出结果是不是-0.000再予处理。

典型案例:UVA746

*****

解决办法是,如果a为正,则输出a+eps, 否则输出a-eps

解决办法是,如果a为正,则输出a+eps, 否则输出a-eps

解决办法是,如果a为正,则输出a+eps, 否则输出a-eps

所以我们应该直接用字符串。

 我:那我以后直接*10! 把误差搞没 最后/10 用int就好了

zj: 你是shadiao吗?那不是59吗......你要加eps啊

zj:但是eps加多少你比赛的时候去试20遍吗?多少大佬死在上面.....

zj:条条大路通罗马(意味深长的眼神)

 

=====题外话====

我已经都不知道该干什么了,先是从早上写出int record=-15.6<<endl这种,又发现自己电脑上word崩了  ppt崩了

codeblocks又不能用 机房的电脑很慢0.1m/10s

如果当初没买xps或者vs也不能用 恐怕我会更可怕的埋怨自己吧.. 

机房明明一点效率没有 还是要大热天跑过来 寝室亦然 

花语学院 十几个收集的明明我就差那两种一共最后三件了 今天花了钻石死活不掉落

它当然可以一直不掉落…… 可我已经五星了啊  不掉落我又有什么办法……

昨晚做梦  梦到写一个题目就差一个精度 最后看也不能看 四五点醒了一次感觉整个人都很累 

hdu第一次还给了我一场离zj他们4题很近的错觉

我没学过的东西太多了 树状数组 主席线段树 很多吧

“这可都是默认他们都会了的东西”

我看起来又慢   又不理解

写模拟那种还很容易错

是啊

还有多远呢

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值