这题主要利用叉积判断点在线段的左侧还是右侧,然后从左到右找到第一条在它右边的线段即可。
暴力直接跑可以过,如果要快点的话,可以加个二分。
#include
#include
#include
using namespace std;
const int maxn = 5e3 + 10;
struct Point{
int x, y;
Point(int x = 0, int y = 0):x(x), y(y) {}
};
struct Edge{
Point a, b;
Edge(Point a, Point b) : a(a), b(b) {}
Edge() {}
};
typedef Point Vector;
Vector operator - (Vector A, Vector B) { return Vector(A.x - B.x, A.y - B.y); }
int ans[maxn];
Edge e[maxn];
int Cross(Vector A, Vector B){
return A.x*B.y - A.y*B.x;
}
bool ok(Point A, Edge e){
Point B = e.a, C = e.b;
if(Cross(B-C, A-C) > 0){
return true;
}else{
return false;
}
}
int main(){
int n, m, x1, y1, x2, y2;
while(~scanf("%d%d%d%d%d%d", &n, &m, &x1, &y1, &x2, &y2)){
if(!n) break;
memset(ans, 0, sizeof(ans));
for(int i = 0; i < n; ++ i){
int u, d;
scanf("%d%d", &u, &d);
e[i] = Edge(Point(u, y1), Point(d, y2));
}
for(int i = 0; i < m; ++ i){
int x, y;
scanf("%d%d", &x, &y);
int j;
for(j = 0; j < n; ++ j){
if(ok(Point(x, y), e[j])){
break;
}
}
ans[j] ++;
}
for(int i = 0; i <= n; ++ i){
printf("%d: %d\n",i, ans[i]);
}
puts("");
}
return 0;
}