POJ-2318 TOYS 计算几何(叉积的用法)

http://poj.org/problem?id=2318

题意:

一个矩形的玩具盒子,用隔板分成很多块,每个隔板的两端分别在矩形的上下边界上,且任两个隔板不会相交。现给定矩形的左上角和右下角坐标,每个隔板两端点的坐标以及一些玩具的坐标,问每个区域内分布有多少玩具?

输入多个样例,每个样例输入6个整数,n,m,x1,y1,x2,y2,n是隔板数,m是玩具个数(x1,y1),(x2,y2)分别是矩形的左上角和右下角坐标,接下来n行,每行输入两个数Ui和Li,代表第i个隔板的上下端点分别是(Ui,y1)和(Li,y2)。隔板按照从左到右的顺序给出,并且任意两隔板不会相交。

接下来m行给出玩具坐标,玩具不会恰好落在隔板上或者矩形边界上。输入0表示输入结束。

输出每个小块中分布的玩具数目。

思路:

对于一个已知位置的玩具,可以二分找出它右边的隔板,需要判断线与点的位置关系,通过向量叉积判断即可。

PS:判断点与直线位置关系

I=AB×BC,当I为正时,点C在AB向量所在直线的左侧;为负时,在右侧,I=0时,点C在直线AB上。

代码:

#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<string>
#include<iomanip>
#include<algorithm>
#include<string.h>
#include<queue>
#include<cmath>
#include<stack>

using namespace std;
const int maxn = 5010;
const int inf = 0x7f7f7f7f;
typedef long long ll;

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, y11, x2, y2;
int U[maxn], L[maxn];
int ans[maxn];

bool ch(int x, int y, int id)
{
    point a = point(L[id], y2), b = point(U[id], y11);//检查编号id的隔板是否在点(x,y)的左侧
    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) {
        memset(ans, 0, sizeof(ans));
        scanf("%d%d%d%d%d", &m, &x1, &y11, &x2, &y2);
        U[0] = L[0] = x1, U[n + 1] = L[n + 1] = x2;
        for (int i = 1; i <= n; i++) scanf("%d%d", &U[i], &L[i]);
        int x, y;
        for (int i = 0; i < m; i++) {
            scanf("%d%d", &x, &y);
            ans[find(x, y)]++;
        }
        for (int i = 0; i <= n; i++) printf("%d: %d\n", i, ans[i]);
        printf("\n");
    }
    system("pause");
    return 0;
}

 

posted on 2021-02-07 17:55  mmn  阅读(80)  评论(0编辑  收藏  举报