【题意】
有一个大箱子,由n个板分为n+1块,标号为0~n已知盒子左上角和右下角的坐标及每个板上下两端的横坐标(板不会交错,且按顺序给出)然后给出玩具的坐标,统计每块空间内玩具个数(保证玩具一定落在空间内)
【解答】
其实就是二分,用叉积的性质。
表示偷懒了,二分一直写不清楚,干脆二分缩小到只剩5个后枚举。
水。。
#include <iostream>
using namespace std;
const int maxn=5005;
struct point
{
int x,y;
};
struct line
{
point a,b;
}a[maxn];
int n,m,x1,x2,y1,y2,sum[maxn];
int xmult(point p1,point p2,point p0)
{
return (p1.x-p0.x)*(p2.y-p0.y)-(p1.y-p0.y)*(p2.x-p0.x);
}
void init()
{
int u,v,i;
a[0].a.x=x1;a[0].a.y=y1;
a[0].b.x=x1;a[0].b.y=y2;
for (i=1;i<=n;i++)
{
scanf("%d %d",&u,&v);
a[i].a.x=u;a[i].a.y=y1;
a[i].b.x=v;a[i].b.y=y2;
}
a[++n].a.x=x2;a[n].a.y=y1;
a[n].b.x=x2;a[n].b.y=y2;
}
int bin(point p)
{
int ll=0,rr=n,mid;
while (ll+5<rr)
{
mid=(ll+rr)/2;
if (xmult(p,a[mid].a,a[mid].b)<=0)
rr=mid;
else
ll=mid;
}
for (int i=ll;i<=rr;i++)
if (xmult(p,a[i].a,a[i].b)>=0 && xmult(p,a[i+1].a,a[i+1].b)<=0)
return i;
}
void work()
{
int i;
point p;
memset(sum,0,sizeof(sum));
for (i=0;i<m;i++)
{
scanf("%d %d",&p.x,&p.y);
sum[bin(p)]++;;
}
for (i=0;i<n;i++)
printf("%d: %d\n",i,sum[i]);
}
int main()
{
freopen("pin.txt","r",stdin);
freopen("pou.txt","w",stdout);
int ff=0;
while (1)
{
scanf("%d",&n);
if (n==0) break;
if (ff) printf("\n");
ff=1;
scanf("%d %d %d %d %d",&m,&x1,&y1,&x2,&y2);
init();
work();
}
return 0;
}