题目大意:
给定一个矩形,中间有n块板把这个矩形分成n+1块,从0开始编号。
保证按照顺序给出并且没有相交。
给定m个点,询问每一个块内有多少个点。
题目分析:
对于每一个点二分所有的线段,然后利用叉积的性质判断它在这条线的左边还是右边,统计答案。
时间复杂度O(mlogn)
(水题一枚╮(╯_╰)╭,我这种蒟蒻也就能做这种题了QAQ)
代码如下:
#include<cstdio>
#include<cstring>
#define N 5005
using namespace std;
struct point{
int x,y;
point(int x=0,int y=0):x(x),y(y){}
}tmp;
struct line{
point a,b;
}a[N];
int n,m,x1,x2,y1,y2;
int ans[N];
int Cross_product(point p1,point p2,point p0)
{
return (p1.x-p0.x)*(p2.y-p0.y)-(p1.y-p0.y)*(p2.x-p0.x);
}
int bin(point c)
{
int l=0,r=n,ans=0;
while(l<=r)
{
int mid=l+r>>1;
if(Cross_product(c,a[mid].a,a[mid].b)>0)
l=mid+1,ans=mid;
else r=mid-1;
}
return ans;
}
int main()
{
for(;;)
{
scanf("%d",&n);
if(!n) break;
memset(ans,0,sizeof(ans));
scanf("%d",&m);
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
a[0].a=point(x1,y1);
a[0].b=point(x1,y2);
a[n+1].a=point(x2,y1);
a[n+1].b=point(x2,y2);
for(int i=1;i<=n;i++)
{
scanf("%d%d",&x1,&x2);
a[i].a=point(x1,y1);
a[i].b=point(x2,y2);
}
for(int i=1;i<=m;i++)
{
scanf("%d%d",&tmp.x,&tmp.y);
ans[bin(tmp)]++;
}
for(int i=0;i<=n;i++)
printf("%d: %d\n",i,ans[i]);
printf("\n");
}
return 0;
}