解决 this problem , 我发现
if(!(p<arr[i]))
和
if(p>=arr[i])
可能有不同的结果(p
是一个 long long
而 arr[i]
是一个 double
) ,因为第一个解决方案被接受而第二个不被接受。为什么?
上下文的完整代码:
#include <bits/stdc++.h>
#define EPS (1e-5)
using namespace std;
typedef long long ll;
double arr[10005];
int main(){
ll D,p;
string s;
while(getline(cin,s)){
stringstream ss(s);
ss>>D>>p;
int n=0;
while(ss>>arr[n]) ++n;
ll dmin=D+1;
if(n<D+1){
double a=arr[n-4];
double b=arr[n-3];
double c=arr[n-2];
double d=arr[n-1];
double den=a*c-b*b;
double s=(c*c-b*d)/den;
double t=(a*d-b*c)/den;
for(int i=n;i<=D;++i)
arr[i]=s*arr[i-2]+t*arr[i-1];
}
for(int i=0;i<=D;++i){
if(!(p<arr[i]))
dmin=min(dmin,D-i);
else
break;
}
if(dmin==0) cout<<"The spider may fall!"<<endl;
else if(dmin==D+1) cout<<"The spider is going to fall!"<<endl;
else cout<<dmin<<endl;
}
}
最佳答案
如果!(a<b)
和 (a>=b)
不同那么最可能的解释是其中一个是 NaN。 任何 涉及 NaN 的比较都会导致 false
, 所以如果 b
是 NaN,则两者都是 (a<b)
和 (a>=b)
将是错误的,并且 !(a<b)
将是真实的。
首先查看您的代码:
double den=a*c-b*b;
double s=(c*c-b*d)/den;
double t=(a*d-b*c)/den;
den
没有明显的原因不能为零,在这种情况下 s
和 t
将是无穷大。然后,您计算:
for(int i=n;i<=D;++i)
arr[i]=s*arr[i-2]+t*arr[i-1];
如果s
和 t
是无穷大,那么产生arr[i]
的总和就有足够的空间成为一个 NaN。两个同号无穷大之和就是无穷大本身,而两个异号无穷大之和就是 NaN。此外,0 和无穷大的乘积是 NaN。
一旦 NaN 进入 arr
,它将传播,因为每个元素都依赖于前一个元素。
所以如果den
,你可能需要做些什么为 0。
关于C++ 比较器保证和内部工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35122122/