题目链接:http://poj.org/problem?id=2318
题意:给你n个挡板,m个点,和一个盒子,挡板把盒子分成了n+1个区域,问你每个区域有多少个点
解析:枚举每个点和邻近的两条线比,在左边的那条线的右边,在右边的那条线的左边,即在这个区域里,我用的是叉乘来判断点在线的哪边
#include <cmath>
#include <algorithm>
#include <iostream>
#include <cstdio>
#include <vector>
#include <cstring>
using namespace std;
const int maxn = 1e5;
const double eps = 1e-5;
struct point
{
int x,y;
point() {}
point(int _x,int _y)
{
x = _x;
y = _y;
}
}b[maxn];
struct line
{
point a,b;
}a[maxn];
int ans[maxn];
int cross(point p0,point p1,point p2)
{
return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);
}
int dot_online(point t1,line l)
{
return cross(t1,l.a,l.b);
}
int main(void)
{
int n,m;
int first = 0;
while(~scanf("%d",&n)&&n)
{
scanf("%d",&m);
point s,e;
memset(ans,0,sizeof(ans));
scanf("%d %d %d %d",&s.x,&s.y,&e.x,&e.y);
a[0].a = s;
a[0].b = point(s.x,e.y);
for(int i=1;i<=n;i++)
{
int u,l;
scanf("%d %d",&u,&l);
a[i].a = point(u,s.y);
a[i].b = point(l,e.y);
}
a[n+1].a = point(e.x,s.y);
a[n+1].b = e;
for(int i=0;i<m;i++)
scanf("%d %d",&b[i].x,&b[i].y);
for(int i=0;i<m;i++)
{
for(int j=0;j<=n;j++)
{
if(dot_online(b[i],a[j])>0 && dot_online(b[i],a[j+1])<0)
{
ans[j]++;
break;
}
}
}
if(first)
puts("");
for(int i=0;i<=n;i++)
printf("%d: %d\n",i,ans[i]);
first = 1;
}
return 0;
}