poj 2318 TOYS 点与矩形的关系

题目链接

题意

有一个矩形盒子,\(n(n\leq 5e4)\)条线段将其分成了\(n+1\)个区域(每条线段的两个端点分别在矩形的上边和下边,且线段互不相交)。现向盒子中扔\(m(m\leq 5e4)\)个玩具,问最终盒子的\(n+1\)个区域中各有多少玩具。数据保证玩具不会扔在线段上。
1240775-20171006212901036-249457746.jpg

思路

假设玩具\(P\)在第\(i\)个区域,其左边为第\(i\)条线段\(A_1B_1\),右边为第\(i+1\)条线段\(A_2B_2\)\(A\)在上边,\(B\)在下边),则有\[\overrightarrow{PA_1}\times\overrightarrow{PB_1}\gt 0 且 \overrightarrow{PA_2}\times\overrightarrow{PB_2}\lt 0\]
并且左边的叉积都大于\(0\),右边都小于\(0\).

因此可以二分查找\(P\)的位置。

也可以先对玩具的横坐标用\(lower\_bound\)确定下来一个小范围,再在这个小范围内二分(直接查找也可以,因为这个范围应该很小)。

Code

#include <cstdio>
#include <cstring>
#include <algorithm>
#define maxn 5010
int up[maxn], down[maxn], ans[maxn], n, m;
using namespace std;
typedef long long LL;
LL vec(LL x1, LL y1, LL x2, LL y2, LL x0, LL y0) {
    return (x1-x0) * (y2-y0) - (x2-x0) * (y1-y0);
}
void work() {
    memset(ans, 0, sizeof ans);
    int x1, y1, x2, y2;
    scanf("%d%d%d%d%d", &m, &x1, &y1, &x2, &y2);
    for (int i = 1; i <= n; ++i) scanf("%d%d", &up[i], &down[i]);
    up[0] = down[0] = x1, up[n+1] = down[n+1] = x2;
    while (m--) {
        int x, y;
        scanf("%d%d", &x, &y);
        int p2 = lower_bound(down, down+n+1, x) - down,
            p1 = lower_bound(up, up+n+1, x) - up;
        if (p1 == p2) { ++ans[p1-1]; continue; }
        if (p1 > p2) swap(p1, p2);
        for (int i = p1; i <= p2; ++i) {
            if (vec(up[i], y1, down[i], y2, x, y) < 0) { ++ans[i-1]; break; }
        }
    }
    for (int i = 0; i <= n; ++i) printf("%d: %d\n", i, ans[i]);
    printf("\n");
}
int main() {
    while (scanf("%d", &n) && n) work();
    return 0;
}

转载于:https://www.cnblogs.com/kkkkahlua/p/7633002.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值