ZOJ1081 Points Within

PS: 判断点是否在多边形内,用的绕圈法,具体参见刘汝佳的训练指南。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <cmath>
using namespace std;

struct point {
    int x, y;
    point(double x=0, double y=0):x(x),y(y) {}
};
point operator - (point A, point B) {
    return point(A.x-B.x, A.y-B.y);
}

double Cross(point A, point B) {
    return A.x*B.y - A.y*B.x;
}
vector<point> v;
vector<point> Contain;
vector<point> check;
int n, m;
const double eps = 1e-10;
int dcmp(double x) {
    if(fabs(x)<eps) return 0;
    else return x < 0 ? -1 : 1;
}

double Dot(point a, point b) {
    return a.x*b.x + a.y*b.y;
}
bool OnSegment(point p, point a1, point a2) {
    return dcmp(Cross(a1-p, a2-p))==0 && dcmp(Dot(a1-p, a2-p))<=0;
}

int isPointIn(point p) {
    int wn = 0;
    for(int i = 0; i < n; i++) {
        if(OnSegment(p, v[i], v[(i+1)%n])) return 1;
        int k = dcmp(Cross(v[(i+1)%n]-v[i], p-v[i]));
        int d1 = dcmp(v[i].y-p.y);
        int d2 = dcmp(v[(i+1)%n].y-p.y);
        if(k>0 && d1<=0 && d2 > 0) wn++;
        if(k<0 && d2<=0 && d1 > 0) wn--;
    }
    if(wn!=0) return 1;
    else return 0;
}

int main()
{
    int T = 1;
    point tmp;
    bool first = false;
    while(scanf("%d", &n)!=EOF && n) {
        if(first) printf("\n");
        else first = true;
        scanf("%d", &m);
        v.clear();
        Contain.clear();
        for(int i = 0; i < n; i++) {
            scanf("%d%d", &tmp.x, &tmp.y);
            Contain.push_back(tmp);
        }
        for(int i = n-1; i >= 0; i--) {
            v.push_back(Contain[i]);
        }
        check.clear();
        for(int i = 0; i < m; i++) {
            scanf("%d%d", &tmp.x, &tmp.y);
            check.push_back(tmp);
        }
        printf("Problem %d:\n", T++);
        for(int i = 0; i < m; i++) {
            int res = isPointIn(check[i]);
            if(res==1) printf("Within\n");
            else printf("Outside\n");
        }
    }
}

ZOJ1081 Points Within,码迷,mamicode.com

时间: 2025-01-02 17:46:15

ZOJ1081 Points Within的相关文章

ZOJ1081 Points Within 点和多边形的位置关系

ZOJ1081 给一个点和一个多边形 判断点在多边形内(边上)还是在多边形外 在多边形外的点引一条射线必然穿过多边形的两条边 而在多边形内的点则不一定. 当然凹多边形有特殊情况 但是总能找到对应位置关系的边来抵消 #include<iostream> #include<stdio.h> #include<stdlib.h> #include<string.h> #include<math.h> #include<algorithm>

ZOJ1081:Points Within——题解

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1081 题目大意:给定一个点数为 n 的多边形,点按照顺序给出,再给出 m 个点,询问每个点是否在多边形内. —————————————————————————————— 计算几何开荒期,所以都算是板子吧……既然是板子那么题解自然也都是集网上之大成. 所以以后也就不多说了.正式往下看题解吧. —————————————————————————————— 这是一道求点是否在一

UVA 10869 - Brownie Points II(树状数组)

UVA 10869 - Brownie Points II 题目链接 题意:平面上n个点,两个人,第一个人先选一条经过点的垂直x轴的线,然后另一个人在这条线上穿过的点选一点作垂直该直线的线,然后划分出4个象限,第一个人得到分数为1,3象限,第二个人为二四象限,问第一个个人按最优取法,能得到最小分数的最大值,和这个值下另一个人的得分可能情况 思路:树状数组,可以枚举一点,如果能求出右上和左下点的个数就好办了,其实用一个树状数组,把y坐标离散化掉,然后记录进来,然后把点按x从左往右,每次删掉点后查询

hdu 4717 The Moving Points(三分)

题目链接:hdu 4717 The Moving Points 题意: 在二维平面上有n个点,每个点给出移动的方向和速度. 问在某个时刻,这些点中最大距离最小是多少,输出时刻和距离. 题解: 我们可以知道,每个点对的距离要么是单调递增,要么是有一个峰的函数. 举例画一下可知道合成的这个函数最多只有一个峰,所以可以用三分求解. 1 #include<bits/stdc++.h> 2 #define F(i,a,b) for(int i=a;i<=b;++i) 3 using namespa

ACM ——Points in Segments

Given n points (1 dimensional) and q segments, you have to find the number of points that lie in each of the segments. A point pi will lie in a segment A B if A ≤ pi ≤ B. For example if the points are 1, 4, 6, 8, 10. And the segment is 0 to 5. Then t

149. Max Points on a Line *HARD* 求点集中在一条直线上的最多点数

Given n points on a 2D plane, find the maximum number of points that lie on the same straight line. /** * Definition for a point. * struct Point { * int x; * int y; * Point() : x(0), y(0) {} * Point(int a, int b) : x(a), y(b) {} * }; */ class Solutio

L - Points on Cycle

Description There is a cycle with its center on the origin. Now give you a point on the cycle, you are to find out the other two points on it, to maximize the sum of the distance between each other you may assume that the radius of the cycle will not

Max Points on a Line

题意:给定n个二维平面上的点,找到某条直线让该直线穿过的点最多,并求出点的个数. 我的想法: 固定两个点作为一条直线,然后遍历其他的点看是否在这条直线上,一边遍历一边记录.最后把该直线上的点数和之前的最大点数进行比较,并取较大者.然后取下一条直线进行相同的操作,但要注意重复的情况,不然会超时. 思路很简单,三个循环便可以完成,时间复杂度达到了n^3. 贴上代码: class Solution { public: int maxPoints(vector<Point>& points)

LeetCode-Max Points On a Line题解

一. 题意描述 Given n points on a 2D plane, find the maximum number of points that lie on the same straight line. 二. 题目分析 看到这道题想到的第一种方法是暴力枚举法,时间复杂度为O(n3),显然是不够好的. 于是我们需要进行一些优化,注意到对于一条直线上的任意两点,他们连线的斜率是相同的.于是我们可以算出指定点到其他所有点的斜率,先使得包含指定点的直线上点数最多,这个过程中可以建立斜率和直线