题目链接:http://poj.org/problem?id=2318
题目大意就是一个矩形,被分成很多块,求每块的玩具数目。
我们首先是要判定这个点,是否在区域内,有叉乘的性质可知,令I =
AB−→−
A
B
→
×
×
BC−→−
B
C
→
, 当I>0时,点C在
AB−→−
A
B
→
的左侧(沿向量方向看去) ,反之亦然,且当I=0时,点C在
AB−→−
A
B
→
上。所以我们只要通过二分的方法,找到第一个在其右侧的隔板即可。
AC代码如下:
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
const int N = 5005;
struct Point{
int x, y;
Point(){}
Point(int _x, int _y):x(_x), y(_y){} //定义两种构造函数
Point operator - (const Point a) const{
return Point (x-a.x, y-a.y);
}
int operator*(const Point a) const{
return x*a.y - y*a.x;
}
};
int n, m, x1, y1, x2, y2;
int U[N], L[N], ans[N];
bool ch(int x, int y, int id)
{
Point a = Point(L[id], y2), b = Point(U[id], y1);
Point c = Point(x, y);
return (c-a) * (b-a) > 0;
}
int find(int x, int y)
{
int l = 0, r = n+1, mid;
while(l < r){
mid = (l+r)>>1;
if(ch(x, y, mid)) l = mid+1;
else r = mid;
}
return l-1;
}
int main()
{
while(~scanf("%d", &n), n){
int i, j;
memset(ans, 0, sizeof(ans));
scanf("%d %d %d %d %d", &m, &x1, &y1, &x2, &y2);
U[0] = L[0] = x1, U[n+1] = L[n+1] = x2;
for(i = 1; i <= n; i++){
scanf("%d %d", &U[i], &L[i]);
}
int x, y;
for(i = 0; i < m; i++){
scanf("%d %d", &x, &y);
ans[find(x, y)]++;
}
for(i = 0; i <= n; i++){
cout << i << ": " << ans[i] << '\n';
}
puts("");
}
return 0;
}