zoukankan      html  css  js  c++  java
  • HDU 1756 Cupid's Arrow 判断点在多边形的内部

    Cupid's Arrow

    Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 1163    Accepted Submission(s): 425


    Problem Description
    传说世上有一支丘比特的箭,凡是被这支箭射到的人,就会深深的爱上射箭的人。
    世上无数人都曾经梦想得到这支箭。Lele当然也不例外。不过他想,在得到这支箭前,他总得先学会射箭。
    日子一天天地过,Lele的箭术也越来越强,渐渐得,他不再满足于去射那圆形的靶子,他开始设计各种各样多边形的靶子。
    不过,这样又出现了新的问题,由于长时间地练习射箭,Lele的视力已经高度近视,他现在甚至无法判断他的箭射到了靶子没有。所以他现在只能求助于聪明的Acmers,你能帮帮他嘛?
    Input
    本题目包含多组测试,请处理到文件结束。
    在每组测试的第一行,包含一个正整数N(2<N<100),表示靶子的顶点数。
    接着N行按顺时针方向给出这N个顶点的x和y坐标(0<x,y<1000)。
    然后有一个正整数M,表示Lele射的箭的数目。
    接下来M行分别给出Lele射的这些箭的X,Y坐标(0<X,Y<1000)。
    Output
    对于每枝箭,如果Lele射中了靶子,就在一行里面输出"Yes",否则输出"No"。
    Sample Input
    4 10 10 20 10 20 5 10 5 2 15 8 25 8
    Sample Output
    Yes No
    Author
    linle
    Source
    这个题是裸的判断点p在多边形内部的, 直接用射线法就可以做, 射线法就是以p为端点,向一个方向做射线,然后看有几个交点,如果交点是奇数,则在内部,偶数,外部,一般选择往右做射线,还有就是判断几个特殊情况.代码中有注释
    /*************************************************************************
        > File Name:            hdu_1756.cpp
        > Author:               Howe_Young
        > Mail:                 1013410795@qq.com
        > Created Time:         2015年04月06日 星期一 09时06分42秒
     ************************************************************************/
    
    #include <cstdio>
    #include <iostream>
    #include <cstring>
    #include <cmath>
    #include <cstdlib>
    #include <algorithm>
    #include <cstdio>
    #define EPS 1e-8
    using namespace std;
    typedef long long LL;
    const int N = 105;
    struct point{
        double x, y;
    };
    point poly[N];
    int n, m;
    double dabs(double a)
    {
        return a < 0 ? -a : a;
    }
    double Min(double a, double b)
    {
        return a < b ? a : b;
    }
    double Max(double a, double b)
    {
        return a > b ? a : b;
    }
    
    bool on_line(point a, point b, point c)//判断点在直线上
    {
        if (c.x >= Min(a.x, b.x) && c.x <= Max(a.x, b.x) && c.y >= Min(a.y, b.y) && c.y <= Max(a.y, b.y))
        {
            return (dabs((c.x - a.x) * (b.y - a.y) - (b.x - a.x) * (c.y - a.y)) <= EPS);
        }
        return false;
    }
    bool inside_polygon(point p, int n)//判断点在多边形内
    {
        int counter = 0;
        double xinter;
        point p1, p2;
        p1 = poly[0];
        for (int i = 1; i <= n; i++)
        {
            p2 = poly[i % n];
            if (on_line(p1, p2, p))//此题在边界不算
                return false;
            if (p.y > Min(p1.y, p2.y))//如果射线交于边的下端点,不算相交,所以是>
            {
                if (p.y <= Max(p1.y, p2.y))
                {
                    if (p.x <= Max(p1.x, p2.x))
                    {
                        if (p1.y != p2.y)//如果射线和边重合,不算
                        {
                            //判断是否满足在这个边的左边,其中(p1.x - p2.x) / (p1.y - p2.y)为tan
                            xinter = (p.y - p2.y) * (p1.x - p2.x) / (p1.y - p2.y) + p2.x;
                            if (p1.x == p2.x || p.x <= xinter)
                                counter++;
                        }
                    }
                }
            }
            p1 = p2;
        }
        if (counter % 2 == 0)
            return false;
        return true;
    }
    int main()
    {
        while (~scanf("%d", &n))
        {
            for (int i = 0; i < n; i++)
            {
                scanf("%lf %lf", &poly[i].x, &poly[i].y);
            }
            cin >> m;
            point p;
            for (int i = 0; i < m; i++)
            {
                cin >> p.x >> p.y;
                if (inside_polygon(p, n))
                    puts("Yes");
                else
                    puts("No");
            }
        }
        return 0;
    }
    View Code
  • 相关阅读:
    tomcat常见错误
    tomcat——大致简介和执行过程
    JSON的基本操作
    VS Code 终端显示问题
    VS Code在本地进行调试和打开本地服务器
    重做了一下我的音乐播放器
    Treimu更新记录1.2.9.0
    Android开发中Eclipse里的智能提示设置
    一次面试经历
    正确处理WPF中Slider值改变事件的方式
  • 原文地址:https://www.cnblogs.com/Howe-Young/p/4397443.html
Copyright © 2011-2022 走看看