萌新刚学OI,求助啊!
  • 板块P1153 点和线
  • 楼主STUDENT00
  • 当前回复3
  • 已保存回复3
  • 发布时间2022/12/10 12:31
  • 上次更新2023/10/26 23:56:59
查看原帖
萌新刚学OI,求助啊!
658786
STUDENT00楼主2022/12/10 12:31

思路: 用next_permutation枚举点的连接顺序,然后建边,最后判断边是否交叉。具体就是求出两条边的斜率式,然后解方程,最后判断解出的x是否在范围内。

代码:

#include<bits/stdc++.h>
#define y1 _y
#define N 15
using namespace std;
int n,p[N];
double x[N],y[N],x1[N],y1[N],x2[N],y2[N]; 
void make(double x1,double y1,double x2,double y2,double &k,double &b){
	k=(y1-y2)/(x1-x2);
	b=y1-k*x1;
}
bool check(){
	for(int i=2;i<=n;i++){
		for(int j=1;j<i;j++){
			double k1,b1,k2,b2;
			make(x1[j],y1[j],x2[j],y2[j],k1,b1);
			make(x1[i],y1[i],x2[i],y2[i],k2,b2);
			if(k1==k2) continue;
			double x=(b2-b1)/(k1-k2);
			if(x>min(x1[j],x2[j])&&x<max(x1[j],x2[j])&&x>min(x1[i],x2[i])&&x<max(x1[i],x2[i])) return 0;
		}
	}
	return 1;
}
int main(){
	while(~scanf("%lf%lf",&x[n+1],&y[n+1])) n++;
	for(int i=1;i<=n;i++) p[i]=i;
	int ans=0;
	do{
		for(int i=1;i<=n;i++){x1[i]=x[p[i]];y1[i]=y[p[i]];x2[i]=x[p[i+1]];y2[i]=y[p[i+1]];}
		x2[n]=x[p[1]];y2[n]=y[p[1]];
		if(check()) ans++;
	}while(next_permutation(p+1,p+n+1));
	printf("%d",ans/n/2);
	return 0;
}
2022/12/10 12:31
加载中...