关于浮点误差
  • 板块学术版
  • 楼主cjh20090318
  • 当前回复8
  • 已保存回复8
  • 发布时间2022/11/4 22:05
  • 上次更新2023/10/27 04:17:09
查看原帖
关于浮点误差
577880
cjh20090318楼主2022/11/4 22:05

CSP-J 2022,T2。

这一题我的方法其实是对的,但是浮点误差让我少了 3030 分,我就痛失了 CQ 的一等。

我是用的数学方法来做此题。

这是我的 7070 分代码:

//the code is from chenjh
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
#define LLL __int128
int main(){
	int k;scanf("%d",&k);
	while(k--){
		LL n,e,d;
		scanf("%lld%lld%lld",&n,&e,&d);
		LL pq=n-e*d+2;
		if((double)pq*pq-4.0*n<0){
			puts("NO");
			continue;
		}
		LL pq1=floor(sqrt((double)pq*pq-4.0*n));
		if((LLL)pq1*pq1==(LLL)pq*pq-4*n && !((pq+pq1)&1) && pq-pq1>=0 && !((pq-pq1)&1)){
			LL ans1=(pq-pq1)>>1,ans2=(pq+pq1)>>1;
			if(ans1>ans2) swap(ans1,ans2);
			printf("%lld %lld\n",ans1,ans2);
		}
		else puts("NO");
	}
    return 0;
}

这是我的 100100 分代码:

//the code is from chenjh
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
#define LLL __int128
int main(){
	int k;scanf("%d",&k);
	while(k--){
		LL n,e,d;
		scanf("%lld%lld%lld",&n,&e,&d);
		LL pq=n-e*d+2;
		if(pq*pq-4*n<0){
			puts("NO");
			continue;
		}
		LL pq1=floor(sqrt(pq*pq-4*n));
		if((LLL)pq1*pq1==(LLL)pq*pq-4*n && !((pq+pq1)&1) && pq-pq1>=0 && !((pq-pq1)&1)){
			LL ans1=(pq-pq1)>>1,ans2=(pq+pq1)>>1;
			if(ans1>ans2) swap(ans1,ans2);
			printf("%lld %lld\n",ans1,ans2);
		}
		else puts("NO");
	}
    return 0;
}

这两份代码的唯一区别是:

第一份代码的这个地方:

if((double)pq*pq-4.0*n<0){//pq 的意思为 p+q
			puts("NO");
			continue;
		}
		LL pq1=floor(sqrt((double)pq*pq-4.0*n));//p-q

修改为:

if(pq*pq-4*n<0){//pq 的意思为 p+q
			puts("NO");
			continue;
		}
		LL pq1=floor(sqrt(pq*pq-4*n));//p-q

这样就 AC 了!!!

请问这样可不可以申诉啊啊啊!

2022/11/4 22:05
加载中...