思路: 用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;
}