为什么这块输出的是 NAN (Not a Number)?
Why this piece is outputting NAN (Not a Number)?
我正在尝试使用 STL 实现最近对问题,但我遇到了一个问题,尤其是在基本条件本身!
如果我尝试打印 (1,1) 和 (0,0) 之间的距离,这段代码 returns nan 会起作用。预期的输出至少是一些数字,我的意思是我认为我没有把它搞砸但它不起作用!!!!!
注意:我已经尝试使用测试距离
distance( make_pair(make_pair(1,1),make_pair(0,0))) 并给出正确的输出。我想还有一些我想念的东西
基本条件(注意我过度使用了对,但这很好):
if(R-L+1<=3)
{
int i,j;
double Temp=1000000.00;
pair < pair < int , int > , pair < int , int > >ret;
for(i=L;i<R;++i)
{
for(j=i+1;j<=R;++j)
{
pair < pair < int , int > , pair < int , int > >PEE=make_pair(X[i],X[j]);
cout<<distance(PEE)<<" ";//This statement outputs nan!!
if(distance(PEE)<Temp)
{
ret=PEE;
Temp=distance(ret);
}
}
}
return ret;
}
那个 cout 语句不会给出正确的输出!!
这里,ret 是 return (Closest pair) 的点。存储距离的温度。
整个函数:
pair < pair < int , int > , pair < int , int > > Divide(int L,int R)
{
if(R-L+1<=3)
{
int i,j;
double Temp=1000000.00;
pair < pair < int , int > , pair < int , int > >ret;
for(i=L;i<R;++i)
{
for(j=i+1;j<=R;++j)
{
pair < pair < int , int > , pair < int , int > >PEE=make_pair(X[i],X[j]);
cout<<distance(PEE)<<" ";
if(distance(PEE)<Temp)
{
ret=PEE;
Temp=distance(ret);
}
}
}
return ret;
}
int M=(R+L)/2;
pair < pair < int , int > , pair < int , int > > P1=Divide(L,M),Chota;
pair < pair < int , int > , pair < int , int > > P2=Divide(M+1,R);
double Delta;
if(distance(P1)<distance(P2))
{
Delta=distance(P1);
Chota=P1;
}
else
{
Delta=distance(P2);
Chota=P2;
}
pair < pair < int , int > , pair < int , int > > P3=Merge(L,R,Delta);
if(distance(P3)<distance(Chota))
return P3;
else
return Chota;
}
距离函数:
double distance(pair < pair < int , int > , pair < int , int > > P)
{
return (double)sqrt(SQUARE(P.first.first-P.second.first)+SQUARE(P.first.second-P.second.second));
}
SQUARE 的宏:
#define SQUARE(x) (x*x)
#define MOD(X) (X>0?X:-1*X)
现在整个程序以备不时之需!
#include<bits/stdc++.h>
#define SQUARE(x) (x*x)
#define MOD(X) (X>0?X:-1*X)
using namespace std;
pair < int , int > P[5000+1],X[5000+1],Y[5000+1];
double distance(pair < pair < int , int > , pair < int , int > > P);
pair < pair < int , int > , pair < int , int > > Merge(int L , int R, double Delta)
{
pair < int , int > Copy[R-L+1],Temp=X[(R+L)/2];
int i,j,k=0;
for(i=L;i<=R;++i)
if(MOD(Temp.first-Y[i].first)<=Delta+1e-9)
Copy[k++]=Y[i];
const int Size=k;
double Dis=10000000;
pair < pair < int , int > , pair < int , int > > ret;
for(i=0;i<Size;++i)
{
for(j=i+1;j<=i+7 && j<Size; ++j)
{
if(distance(make_pair(Copy[i],Copy[j]))<Dis)
{
ret=make_pair(Copy[i],Copy[j]);
Dis=distance(ret);
}
}
}
return ret;
}
pair < pair < int , int > , pair < int , int > > Divide(int L,int R)
{
if(R-L+1<=3)
{
int i,j;
double Temp=1000000.00;
pair < pair < int , int > , pair < int , int > >ret;
for(i=L;i<R;++i)
{
for(j=i+1;j<=R;++j)
{
pair < pair < int , int > , pair < int , int > >PEE=make_pair(X[i],X[j]);
cout<<distance(PEE)<<" ";
if(distance(PEE)<Temp)
{
ret=PEE;
Temp=distance(ret);
}
}
}
return ret;
}
int M=(R+L)/2;
pair < pair < int , int > , pair < int , int > > P1=Divide(L,M),Chota;
pair < pair < int , int > , pair < int , int > > P2=Divide(M+1,R);
double Delta;
if(distance(P1)<distance(P2))
{
Delta=distance(P1);
Chota=P1;
}
else
{
Delta=distance(P2);
Chota=P2;
}
pair < pair < int , int > , pair < int , int > > P3=Merge(L,R,Delta);
if(distance(P3)<distance(Chota))
return P3;
else
return Chota;
}
bool cmp(pair < int , int > A , pair < int , int > B){return A.second<B.second;}
int main()
{
int N,i;
scanf("%d",&N);
for(i=0;i<N;++i)
{
scanf("%d%d",&P[i].first,&P[i].second);
Y[i]=X[i]=P[i];
}
sort(X,X+N);
sort(Y,Y+N,cmp);
Divide(0,N-1);
return 0;
}
double distance(pair < pair < int , int > , pair < int , int > > P)
{
return (double)sqrt(SQUARE(P.first.first-P.second.first)+SQUARE(P.first.second-P.second.second));
}
#define SQUARE(x) (x*x)
可能会产生负值,例如
cout << SQUARE(-1-2) << endl;
在 -1 - 2*-1 - 2
中得到解析并生成 -1
。
最好避免使用宏,但是如果你使用这个,就制作它
#define SQUARE(x) ((x)*(x))
运行 这通过 g++ -E
的预处理步骤非常清楚地显示了您的宏使用导致的问题。预处理前:
double distance(pair < pair < int , int > , pair < int , int > > P)
{
return (double)sqrt(SQUARE(P.first.first-P.second.first)+SQUARE(P.first.second-P.second.second));
}
预处理后:
double distance(pair < pair < int , int > , pair < int , int > > P)
{
return (double)sqrt((P.first.first-P.second.first*P.first.first-P.second.first)+(P.first.second-P.second.second*P.first.second-P.second.second));
}
这几乎肯定不是您想要的。正如您所看到的,这会产生对 sqrt
的否定论证,然后它将为您提供您所看到的 NaN。
要正确编写宏,您可以查看 AlexD 的答案,但老实说,我认为这里更好的方法是不使用宏,而只使用标准库中的正方形函数和 abs
函数。
我正在尝试使用 STL 实现最近对问题,但我遇到了一个问题,尤其是在基本条件本身!
如果我尝试打印 (1,1) 和 (0,0) 之间的距离,这段代码 returns nan 会起作用。预期的输出至少是一些数字,我的意思是我认为我没有把它搞砸但它不起作用!!!!!
注意:我已经尝试使用测试距离 distance( make_pair(make_pair(1,1),make_pair(0,0))) 并给出正确的输出。我想还有一些我想念的东西
基本条件(注意我过度使用了对,但这很好):
if(R-L+1<=3)
{
int i,j;
double Temp=1000000.00;
pair < pair < int , int > , pair < int , int > >ret;
for(i=L;i<R;++i)
{
for(j=i+1;j<=R;++j)
{
pair < pair < int , int > , pair < int , int > >PEE=make_pair(X[i],X[j]);
cout<<distance(PEE)<<" ";//This statement outputs nan!!
if(distance(PEE)<Temp)
{
ret=PEE;
Temp=distance(ret);
}
}
}
return ret;
}
那个 cout 语句不会给出正确的输出!!
这里,ret 是 return (Closest pair) 的点。存储距离的温度。
整个函数:
pair < pair < int , int > , pair < int , int > > Divide(int L,int R)
{
if(R-L+1<=3)
{
int i,j;
double Temp=1000000.00;
pair < pair < int , int > , pair < int , int > >ret;
for(i=L;i<R;++i)
{
for(j=i+1;j<=R;++j)
{
pair < pair < int , int > , pair < int , int > >PEE=make_pair(X[i],X[j]);
cout<<distance(PEE)<<" ";
if(distance(PEE)<Temp)
{
ret=PEE;
Temp=distance(ret);
}
}
}
return ret;
}
int M=(R+L)/2;
pair < pair < int , int > , pair < int , int > > P1=Divide(L,M),Chota;
pair < pair < int , int > , pair < int , int > > P2=Divide(M+1,R);
double Delta;
if(distance(P1)<distance(P2))
{
Delta=distance(P1);
Chota=P1;
}
else
{
Delta=distance(P2);
Chota=P2;
}
pair < pair < int , int > , pair < int , int > > P3=Merge(L,R,Delta);
if(distance(P3)<distance(Chota))
return P3;
else
return Chota;
}
距离函数:
double distance(pair < pair < int , int > , pair < int , int > > P)
{
return (double)sqrt(SQUARE(P.first.first-P.second.first)+SQUARE(P.first.second-P.second.second));
}
SQUARE 的宏:
#define SQUARE(x) (x*x)
#define MOD(X) (X>0?X:-1*X)
现在整个程序以备不时之需!
#include<bits/stdc++.h>
#define SQUARE(x) (x*x)
#define MOD(X) (X>0?X:-1*X)
using namespace std;
pair < int , int > P[5000+1],X[5000+1],Y[5000+1];
double distance(pair < pair < int , int > , pair < int , int > > P);
pair < pair < int , int > , pair < int , int > > Merge(int L , int R, double Delta)
{
pair < int , int > Copy[R-L+1],Temp=X[(R+L)/2];
int i,j,k=0;
for(i=L;i<=R;++i)
if(MOD(Temp.first-Y[i].first)<=Delta+1e-9)
Copy[k++]=Y[i];
const int Size=k;
double Dis=10000000;
pair < pair < int , int > , pair < int , int > > ret;
for(i=0;i<Size;++i)
{
for(j=i+1;j<=i+7 && j<Size; ++j)
{
if(distance(make_pair(Copy[i],Copy[j]))<Dis)
{
ret=make_pair(Copy[i],Copy[j]);
Dis=distance(ret);
}
}
}
return ret;
}
pair < pair < int , int > , pair < int , int > > Divide(int L,int R)
{
if(R-L+1<=3)
{
int i,j;
double Temp=1000000.00;
pair < pair < int , int > , pair < int , int > >ret;
for(i=L;i<R;++i)
{
for(j=i+1;j<=R;++j)
{
pair < pair < int , int > , pair < int , int > >PEE=make_pair(X[i],X[j]);
cout<<distance(PEE)<<" ";
if(distance(PEE)<Temp)
{
ret=PEE;
Temp=distance(ret);
}
}
}
return ret;
}
int M=(R+L)/2;
pair < pair < int , int > , pair < int , int > > P1=Divide(L,M),Chota;
pair < pair < int , int > , pair < int , int > > P2=Divide(M+1,R);
double Delta;
if(distance(P1)<distance(P2))
{
Delta=distance(P1);
Chota=P1;
}
else
{
Delta=distance(P2);
Chota=P2;
}
pair < pair < int , int > , pair < int , int > > P3=Merge(L,R,Delta);
if(distance(P3)<distance(Chota))
return P3;
else
return Chota;
}
bool cmp(pair < int , int > A , pair < int , int > B){return A.second<B.second;}
int main()
{
int N,i;
scanf("%d",&N);
for(i=0;i<N;++i)
{
scanf("%d%d",&P[i].first,&P[i].second);
Y[i]=X[i]=P[i];
}
sort(X,X+N);
sort(Y,Y+N,cmp);
Divide(0,N-1);
return 0;
}
double distance(pair < pair < int , int > , pair < int , int > > P)
{
return (double)sqrt(SQUARE(P.first.first-P.second.first)+SQUARE(P.first.second-P.second.second));
}
#define SQUARE(x) (x*x)
可能会产生负值,例如
cout << SQUARE(-1-2) << endl;
在 -1 - 2*-1 - 2
中得到解析并生成 -1
。
最好避免使用宏,但是如果你使用这个,就制作它
#define SQUARE(x) ((x)*(x))
运行 这通过 g++ -E
的预处理步骤非常清楚地显示了您的宏使用导致的问题。预处理前:
double distance(pair < pair < int , int > , pair < int , int > > P)
{
return (double)sqrt(SQUARE(P.first.first-P.second.first)+SQUARE(P.first.second-P.second.second));
}
预处理后:
double distance(pair < pair < int , int > , pair < int , int > > P)
{
return (double)sqrt((P.first.first-P.second.first*P.first.first-P.second.first)+(P.first.second-P.second.second*P.first.second-P.second.second));
}
这几乎肯定不是您想要的。正如您所看到的,这会产生对 sqrt
的否定论证,然后它将为您提供您所看到的 NaN。
要正确编写宏,您可以查看 AlexD 的答案,但老实说,我认为这里更好的方法是不使用宏,而只使用标准库中的正方形函数和 abs
函数。