好心的各位大佬们, 请问为什么用next_permutation会错,而用dfs才对呢?
#include <bits/stdc++.h>
#define lowbit(x) x&-x
using namespace std;
/*
next_permutation解法
*/
const int maxv=1200000;
const int maxNum=0x7fffffff;
const double PI=3.1415927;
const double eps=1e-6;
const int mod=1e9+7;
typedef long long LL;
struct Point{
double x,y;
}all[maxv],all1[maxv];
int len=0,a[maxv];
double cross(Point a,Point b){
return a.x*b.y-a.y*b.x;
}
bool ifInter(Point x1,Point y1,Point x2,Point y2){
double abc=cross(Point{y1.x-x1.x,y1.y-x1.y},Point{x2.x-x1.x,x2.y-x1.y});
double abd=cross(Point{y1.x-x1.x,y1.y-x1.y},Point{y2.x-x1.x,y2.y-x1.y});
if((abc>0&&abd>0)||(abc<0&&abd<0)) return false;
swap(x1,x2),swap(y1,y2);
abc=cross(Point{y1.x-x1.x,y1.y-x1.y},Point{x2.x-x1.x,x2.y-x1.y});
abd=cross(Point{y1.x-x1.x,y1.y-x1.y},Point{y2.x-x1.x,y2.y-x1.y});
return (abc>0&&abd<0)||(abc<0&&abd>0);
}
int main()
{
int x,y,ans=0;
while(scanf("%d %d",&x,&y)!=EOF) all1[++len]=Point{x,y};
for(int i=1;i<=len;i++) a[i]=i;
do{
bool flag=true;
for(int i=2;i<len-1;i++)
if(ifInter(all1[a[len]],all1[a[1]],all1[a[i]],all1[a[i+1]])){flag=false;break;}
if(flag){ans++;}
}while(next_permutation(a+1,a+len+1));
printf("%d",ans/len/2);
return 0;
}
#include <bits/stdc++.h>
#define lowbit(x) x&-x
using namespace std;
/*
dfs求法
*/
const int maxv=1200000;
const int maxNum=0x7fffffff;
const double PI=3.1415927;
const double eps=1e-6;
const int mod=1e9+7;
typedef long long LL;
struct Point{
double x,y;
}all[maxv],all1[maxv];
int len=0,a[maxv],ans=0;
bool cho[maxv];
double cross(Point a,Point b){ //向量乘积计算
return a.x*b.y-a.y*b.x;
}
bool ifInter(Point x1,Point y1,Point x2,Point y2){ //判断是否任意两条直线都不相交
double abc=cross(Point{y1.x-x1.x,y1.y-x1.y},Point{x2.x-x1.x,x2.y-x1.y});
double abd=cross(Point{y1.x-x1.x,y1.y-x1.y},Point{y2.x-x1.x,y2.y-x1.y});
if((abc>0&&abd>0)||(abc<0&&abd<0)) return false;
swap(x1,x2),swap(y1,y2);
abc=cross(Point{y1.x-x1.x,y1.y-x1.y},Point{x2.x-x1.x,x2.y-x1.y});
abd=cross(Point{y1.x-x1.x,y1.y-x1.y},Point{y2.x-x1.x,y2.y-x1.y});
return (abc>0&&abd<0)||(abc<0&&abd>0);
}
void dfs(int d) //找全排列
{
if(d>len)
{
int i;
for(i=2;i<len-1;i++)
if(ifInter(all1[a[len]],all1[a[1]],all1[a[i]],all1[a[i+1]]))
break;
if(i==len-1){
ans++;
}
return;
}
for(int i=1;i<=len;i++)
if(!cho[i])
{
int j;
a[d]=i;
for(j=1;j<d-2;j++)
if(ifInter(all1[a[d-1]],all1[a[d]],all1[a[j]],all1[a[j+1]]))
break;
if(j>=d-2)
{
cho[i]=true;
dfs(d+1);
cho[i]=false;
}
}
}
int main()
{
int x,y;
while(scanf("%d %d",&x,&y)!=EOF) all1[++len]=Point{x,y};
for(int i=1;i<=len;i++) a[i]=i;
dfs(1);
printf("%d",ans/len/2);
return 0;
}
两种方法样例都过了,第一种四个点全wa,第二种ac了。 好心的各位大佬帮帮忙qwq!