【题目大意】给定一个箱子的左上角坐标和右上角坐标。给定n个隔板的端点坐标【保证隔板不相交】,内部隔间从0到n编号。
给定m个玩具的坐标【保证玩具在箱子内部且不在隔板上】,每个玩具在一个隔间内。
问每个隔间内有多少个玩具。
首先用叉积判玩具在隔板的哪个方位。我们利用二分找到玩具右边的第一个隔板,然后把这个隔间的答案加一。
具体有些细节看代码吧。
#include<cstdio>
#include<cstring>
using namespace std;
struct point{
int x,y;
point(int _x=0,int _y=0){x=_x,y=_y;}
friend inline int operator *(const point &a,const point &b){
return a.x*b.y-a.y*b.x;
}
friend inline point operator +(const point &a,const point &b){
return point(a.x+b.x,a.y+b.y);
}
friend inline point operator -(const point &a,const point &b){
return point(a.x-b.x,a.y-b.y);
}
}toy,up[10000],down[10000],U,D;
int ans[233333],n,m;
//a is toy
//(b->a)*(b->c)
//如果玩具在隔板bc的左边,返回真,否则返回假。
bool check(point a,point b,point c){
return (c-b)*(a-b)>0;
}
int main(){
while(scanf("%d",&n)&&n){
memset(ans,0,sizeof(ans));
scanf("%d",&m);
scanf("%d%d%d%d",&U.x,&U.y,&D.x,&D.y);
for(int i=1;i<=n;++i){
scanf("%d%d",&up[i].x,&down[i].x);
up[i].y=U.y,down[i].y=D.y;
}
for(int i=1;i<=m;++i){
scanf("%d%d",&toy.x,&toy.y);
//注意二分的上下界。
int l=1,r=n+1;
while(l<r){
int mid=(l+r)>>1;
if(check(toy,down[mid],up[mid]))
r=mid;
else l=mid+1;
}
//注意隔间的编号。第L个隔板左边对应第L-1个隔间。
ans[l-1]++;
}
for(int i=0;i<=n;++i)
printf("%d: %d\n",i,ans[i]);
putchar('\n');
}
}