疑问
查看原帖
疑问
41476
gyh20楼主2021/6/17 09:27

这是 1818 分被卡精度的代码:

#include<bits/stdc++.h>
#define re register
using namespace std;
inline int read(){
	re int t=0;re char v=getchar();
	while(v<'0')v=getchar();
	while(v>='0')t=(t<<3)+(t<<1)+v-48,v=getchar();
	return t;
}
int n,a[100002],stk[100002],tp;
inline bool cmp(re int x,re int y,re int z){return 1ll*(a[x]-a[y])*(y-z)>1ll*(a[y]-a[z])*(x-y);}
int main(){
	n=read();
	for(re int i=1;i<=n;++i)a[i]=read();
	stk[tp=1]=1;
	for(re int i=2;i<=n+1;++i){
		while(tp&&cmp(i,stk[tp],stk[tp-1]))--tp;
		stk[++tp]=i;
	}
	for(re int i=1;i<=tp;++i){
		re int l=stk[i-1],r=stk[i];
		for(re int j=l+1;j<=r&&j<=n;++j)printf("%lld\n",100000ll*a[l]+100000ll*(a[r]-a[l])*(j-l)/(r-l));
	}
}

这是 AC 代码

#include<bits/stdc++.h>
#define re register
using namespace std;
inline int read(){
	re int t=0;re char v=getchar();
	while(v<'0')v=getchar();
	while(v>='0')t=(t<<3)+(t<<1)+v-48,v=getchar();
	return t;
}
int n,a[100002],stk[100002],tp;
inline bool cmp(re int x,re int y,re int z){return 1ll*(a[x]-a[y])*(y-z)>1ll*(a[y]-a[z])*(x-y);}
int main(){
	n=read();
	for(re int i=1;i<=n;++i)a[i]=read();
	stk[tp=1]=1;
	for(re int i=2;i<=n+1;++i){
		while(tp&&cmp(i,stk[tp],stk[tp-1]))--tp;
		stk[++tp]=i;
	}
	for(re int i=1;i<=tp;++i){
		re int l=stk[i-1],r=stk[i];
		for(re int j=l+1;j<=r&&j<=n;++j)printf("%lld\n",(100000ll*a[l]*(r-l)+100000ll*(a[r]-a[l])*(j-l))/(r-l));
	}
}

两份代码唯一的区别在于输出

一个是

printf("%lld\n",100000ll*a[l]+100000ll*(a[r]-a[l])*(j-l)/(r-l));

另一个是

printf("%lld\n",(100000ll*a[l]*(r-l)+100000ll*(a[r]-a[l])*(j-l))/(r-l));

没有使用 double,不应该出现精度误差,为什么这两个式子的计算结果会不一样,而且是下面的一个 AC?

应该不是炸 long long 的问题,因为所有变量都强转了 long long,并且如果要炸也是下面一个炸。

求大佬解答。

2021/6/17 09:27
加载中...