一个玩具箱被n个挡板分成n+1快,挡板不会互相交叉。将m个玩具扔进去,求分别被扔进了哪个区域。
主要算法就是判断点与线段的关系,排序后从左往右依此判别即可。
//Memory: 480K
//Time: 485MS
#include <iostream>
#include <math.h>
#include <algorithm>
using namespace std;
struct POINT //点
{
double x,y;
POINT():x(0),y(0){};
POINT(double _x, double _y):x(_x),y(_y){};
};
struct LINESEG //线段
{
POINT s;
POINT e;
LINESEG(POINT a, POINT b) { s=a; e=b;}
LINESEG() { }
};
double relation_lr(POINT p,LINESEG l) //return<0 p在l左侧 return>0 p在l右侧
{
double a,b,c;
a=l.e.y-l.s.y;
b=l.s.x-l.e.x;
c=l.e.x*l.s.y-l.s.x*l.e.y;
return (a*p.x+b*p.y+c);
}
bool cmpl(LINESEG l1,LINESEG l2)
{
if(l1.s.x==l2.s.x)
return l1.e.x<l2.e.x;
return l1.s.x<l2.s.x;
}
bool cmpp(POINT p1,POINT p2)
{
return p1.x<p2.x;
}
int main()
{
POINT p[5005];
LINESEG l[5005];
double x1,y1,x2,y2;
int n,m;
int num[5005];
int flag=true;
while(cin>>n && n)
{
cin>>m>>x1>>y1>>x2>>y2;
l[0].s.x=l[0].e.x=x1;
l[0].s.y=l[n+1].s.y=y2;
l[0].e.y=l[n+1].e.y=y1;
l[n+1].s.x=l[n+1].e.x=x2;
int i,j;
for(i=0;i<=n;i++)
num[i]=0;
for(i=1;i<=n;i++)
{
cin>>l[i].e.x>>l[i].s.x;
l[i].e.y=y1;
l[i].s.y=y2;
}
for(i=1;i<=m;i++)
cin>>p[i].x>>p[i].y;
sort(l,l+n+1,cmpl);
sort(p+1,p+m+1,cmpp);
i=0;j=1;
while(i<=n)
{
if(relation_lr(p[j],l[i+1])>0)
{
i++;
}
else if(relation_lr(p[j],l[i])>0)
{
num[i]++;
j++;
}
else if(relation_lr(p[j],l[i])<0)
{
i--;
}
if(j>m)
break;
}
if(!flag)
cout<<endl;
for(i=0;i<=n;i++)
cout<<i<<": "<<num[i]<<endl;
flag=false;
}
return 0;
}