这题计算几何的部分还是比较简单的,重点是那个二分有点麻烦(大牛忽略),每次写二分自己都得用笔模拟一番,然后才能确定。
因为y1,y2是公共的,所以存储的时候线段的时候只要存储x的坐标就可以了。然后就是判断是在右边还是在左边。
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
const int N=5005;
struct Line
{
int x1,x2;
}line[N];
int x1,x2,y1,y2,n,m,num[N];
int judge(int x,int y,int id)
{
int a1=line[id].x1-x,a2=line[id].x2-x;
int b1=y1-y,b2=y2-y;
return a1*b2-a2*b1;
}
int main()
{
int x,y,k=0;
while(scanf("%d",&n),n!=0)
{
scanf("%d%d%d%d%d",&m,&x1,&y1,&x2,&y2);
for(int i=1;i<=n;i++)
scanf("%d%d",&line[i].x1,&line[i].x2);
memset(num,0,sizeof(num));
for(int i=1;i<=m;i++)
{
scanf("%d%d",&x,&y);
if(judge(x,y,1)<0)//这里要注意一下
{
num[0]++;
continue;
}
if(judge(x,y,n)>0)//这里也要注意,通过画图可以发现,这里需要单独讨论一下。
{
num[n]++;
continue;
}
int l=1,r=n;//这里是二分
while(r-l>1)
{
int mid=(l+r)/2;
if(judge(x,y,mid)<0)
r=mid;
else
l=mid;
}
num[l]++;
}
if(k>0)
printf("\n");
k++;
for(int i=0;i<=n;i++)
printf("%d: %d\n",i,num[i]);
}
return 0;
}