very simple 一点都不simple =。=
要求点能被多边形中选出的三角形包含的个数,这个需要考虑其对立面,总数减去不包含的个数(ps 题解真心强)
不包含的个数的话,以一个点A为初始点,顺时针找到B ,AB形成的直线在p的右侧,此时构成的三角形个数为(A与下面k个点中选2个构成的三角形的个数),扫一圈,就可求出不包含的
#include<stdio.h>
#include<iostream>
#include<math.h>
#include<string.h>
using namespace std;
#define eps 1e-8
#define ll __int64
int sig(double x) {return (x>eps)-(x<-eps);}
struct P
{
double x,y;
P(double a=0,double b=0):x(a),y(b){}
P operator +(const P &a)const{
return P(x+a.x,y+a.y);
}
P operator -(const P &a)const{
return P(x-a.x,y-a.y);
}
P operator *(const double &a)const{
return P(x*a,y*a);
}
P operator /(const double &a)const{
return P(x/a,y/a);
}
double operator *(const P &a)const{
return (x*a.x+y*a.y);
}
double operator ^(const P &a)const{
return (x*a.y-y*a.x);
}
};
P p[100100];
int main()
{
ll n;
while(scanf("%I64d",&n)!=EOF)
{
for(int i=0;i<n;i++)
scanf("%lf%lf",&p[i].x,&p[i].y);
p[n]=p[0];
int t;
scanf("%d",&t);
while(t--)
{
P q;
scanf("%lf%lf",&q.x,&q.y);
int flag=0;
for(int i=0;i<n;i++)
{
if(sig((p[i]-q)^(p[i+1]-q))<=0)
flag++;
}
//printf("%d\n",flag);
if(flag!=n)
{
printf("0\n");
continue;
}
ll num;
ll sum=(n*(n-1)*(n-2))/6;
int j=0;
for(int i=0;i<n;i++)
{
if(i==0) num=0;
else num=(num-1);
while(sig((p[i]-q)^(p[j]-q))<=0)
{
if(j!=i)
{num++;}
j=(j+1)%n;
}
//printf("%I64d %d\n",num,j);
sum-=(num*(num-1)/2);
}
printf("%I64d\n",sum);
}
}
return 0;
}