zoukankan      html  css  js  c++  java
  • 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
    ", i, ans[i]);
            printf("
    ");
        }
        system("pause");
        return 0;
    }
  • 相关阅读:
    字节跳动总监知乎5716赞的Java开发笔记
    刚面完阿里Java高级岗40K的offer,这些技术你必须要掌握!
    HDOJ 1253 胜利大逃亡(bfs)
    swjtu 1962 A+B(模拟)
    swjtu 2213 A Game About Cards(模拟题)
    HDU 1544 Palindromes(回文子串)
    第八章 异常控制流
    第四讲 深入介绍信号与槽
    第三讲 对话框的创建
    第二讲 窗口部件的布局与通信
  • 原文地址:https://www.cnblogs.com/sweetlittlebaby/p/14386168.html
Copyright © 2011-2022 走看看