笨蛋蒟蒻求助各位大佬!为什么
  • 板块P1153 点和线
  • 楼主Butane
  • 当前回复1
  • 已保存回复1
  • 发布时间2021/7/9 00:29
  • 上次更新2023/11/4 18:21:54
查看原帖
笨蛋蒟蒻求助各位大佬!为什么
403799
Butane楼主2021/7/9 00:29

好心的各位大佬们, 请问为什么用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!

2021/7/9 00:29
加载中...