题目就是要求解有多少个点可以被至少一个三角形围住,这个点可以在三角形的边上
题解:
每一个点肯定会在最大的凸包里面,所以我们求解一个凸包,然后二分点,寻找这样的三角形即可
#include<math.h>
#include<stdio.h>
#include<stdlib.h>
#include<iostream>
#include<algorithm>
using namespace std;
#define MAXN 10005
const double eps=1e-8;
struct Point
{
double x,y;
Point(){}
Point(double _X, double _Y){
x = _X; y = _Y;
}
};
Point P[MAXN];
int Stack[MAXN],top;///下标从0开始计数到top
double Cross(Point p1,Point p2,Point p3){
return (p2.x-p1.x)*(p3.y-p1.y)-(p2.y-p1.y)*(p3.x-p1.x);
}
double Dis(Point A, Point B){
return sqrt((A.x-B.x)*(A.x-B.x) + (A.y-B.y)*(A.y-B.y));
}
Point operator - (Point A,Point B){
return Point(A.x-B.x, A.y-B.y);
}
Point operator + (Point A, Point B){
return Point(A.x+B.x, A.y+B.y);
}
Point operator * (Point A, double p){
return Point(A.x*p, A.y*p);
}
bool operator == (Point A, Point B){
return (A.x-B.x) == 0 && (A.y-B.y) == 0;
}
int sgn(double x)
{
if(fabs(x)<eps)
return 0;
if(x<0)
return -1;
return 1;
}
bool cmp(Point A, Point B)///按极角升序排序,若角度相等距离小的在前面
{
double temp = sgn(Cross(P[0],A,B));
if(temp > 0) return true;
else if(temp==0&&(sgn(Dis(P[0], A) - Dis(P[0], B)))<=0) return true;
else return false;
}
void Graham(int n)
{
double xx=P[0].x,yy=P[0].y;
int id=0;//找到y坐标最小的点,若有多个选择x坐标最小的记录下标
for(int i=1;i<n;i++){
if(P[i].y<yy || (P[i].y==yy&&P[i].x<xx)){
xx = P[i].x;
yy = P[i].y;
id = i;
}
}
Point T=P[0];
P[0]=P[id];
P[id]=T;
sort(P+1,P+n,cmp);
if(n==1){
top=1;
Stack[0]=0;
return;
}
if(n==2){
top=2;
Stack[0]=0;
Stack[1]=1;
return ;
}
Stack[0]=0;
Stack[1]=1;
top=2;
for(int i=2;i<n;i++)
{
while(top>1&&sgn(Cross(P[Stack[top-2]],P[Stack[top-1]],P[i]))<=0)
top--;
Stack[top++]=i;
}
}
bool judge(Point temp)
{
int left,right,mid;
double t1,t2,t3;
left=1,right=top-2;
while(left<=right)
{
mid=(left+right)/2;
Point a=P[Stack[0]],b=P[Stack[mid]],c=P[Stack[mid+1]];
t1=Cross(a,b,temp);
t2=Cross(a,c,temp);
if(t1>=0&&t2<=0){
t3=Cross(b,c,temp);
if(t3>=0)
return true;
return false;
}
if(t1<0)
right=mid-1;
else
left=mid+1;
}
return false;
}
int main()
{
int n,s;
//freopen("in.txt","r",stdin);
while(scanf("%d",&n)!=EOF)
{
for(int i=0;i<n;i++)
scanf("%lf%lf",&P[i].x,&P[i].y);
Graham(n);
scanf("%d",&s);
int ans=0;
Point num;
while(s--)
{
scanf("%lf%lf",&num.x,&num.y);
if(judge(num))
ans++;
}
printf("%d\n",ans);
}
return 0;
}