POJ 2318-TOYS 叉积+二分

题目链接:http://poj.org/problem?id=2318
题目大意就是一个矩形,被分成很多块,求每块的玩具数目。
我们首先是要判定这个点,是否在区域内,有叉乘的性质可知,令I = A B × B C , 当I>0时,点C在 A B 的左侧(沿向量方向看去) ,反之亦然,且当I=0时,点C在 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;
}

猜你喜欢

转载自blog.csdn.net/water_zero_saber/article/details/80487671