SGU124 Broken line
2015-06-04 13:51
204 查看
SGU124 Broken line
题目大意
给出围成一个简单多边形的所有线段,询问一个点在多边形内、外,或是边界上算法思路
先构造出多边形,然后通过转角法得出点与多边形的位置关系,具体为:假设该点向右发出一条平行于x轴的射线,然后沿着多边形走一圈
– 如果从射线或射线下方,到达射线上方,则计数器加1
– 如果从射线上方,到达射线或射线下方,则计数器减1
最后如果计数器为0则在多边形外,否则在多边形内,边界上的情况特判
时间复杂度: O(N)O(N)
代码
/** * Copyright © 2015 Authors. All rights reserved. * * FileName: 124.cpp * Author: Beiyu Li <sysulby@gmail.com> * Date: 2015-06-04 */ #include <bits/stdc++.h> using namespace std; #define rep(i,n) for (int i = 0; i < (n); ++i) #define For(i,s,t) for (int i = (s); i <= (t); ++i) #define foreach(i,c) for (__typeof(c.begin()) i = c.begin(); i != c.end(); ++i) typedef long long LL; typedef pair<int, int> Pii; const int inf = 0x3f3f3f3f; const LL infLL = 0x3f3f3f3f3f3f3f3fLL; typedef complex<int> Point; typedef complex<int> Vector; #define X real() #define Y imag() int dot(Vector u, Vector v) { return u.X * v.X + u.Y * v.Y; } int cross(Vector u, Vector v) { return u.X * v.Y - u.Y * v.X; } typedef vector<Point> Polygon; int in_polygon(Point p, const Polygon &g) { int wn = 0; for (int i = 0, m = g.size(); i < m; ++i) { Point v1 = g[i] - p, v2 = g[(i+1)%m] - p; int c = cross(v1, v2), d = dot(v1, v2); if (!c && d <= 0) return 0; int d1 = v1.Y, d2 = v2.Y; if (c > 0 && d1 <= 0 && d2 > 0) ++wn; if (c < 0 && d2 <= 0 && d1 > 0) --wn; } return wn? 1: -1; } const int maxn = 10000 + 5; int psz; struct Edge { int v; Edge *next; } epool[maxn*2], *e[maxn]; void add_edge(int u, int v) { Edge *i = epool + psz++; i->v = v; i->next = e[u]; e[u] = i; } int n, tot; Pii p[maxn*2]; map<Pii, int> mp; bool vis[maxn*2]; Polygon g; int get_id(Pii o) { if (mp.count(o)) return mp[o]; return p[tot] = o, mp[o] = tot++; } void dfs(int u, Polygon &g) { vis[u] = true; g.push_back(Point(p[u].first, p[u].second)); for (Edge *i = e[u]; i; i = i->next) { int v = i->v; if (!vis[v]) dfs(v, g); } } int main() { int x, y; scanf("%d", &n); rep(i,n) { scanf("%d%d", &x, &y); int u = get_id(Pii(x, y)); scanf("%d%d", &x, &y); int v = get_id(Pii(x, y)); add_edge(u, v); add_edge(v, u); } dfs(0, g); scanf("%d%d", &x, &y); int res = in_polygon(Point(x, y), g); puts(res? res > 0? "INSIDE": "OUTSIDE": "BORDER"); return 0; }
相关文章推荐
- 我的第一个HTML5应用
- iOS_引入代码块的步骤
- 黑马程序员-Java之自定义图形化界面的浏览器访问本地的Tomcat服务器
- Android开发模板------自己定义SimpleCursorAdapter的使用
- 构造函数
- DBA 给某用户赋予某张数据库表的某种操作权限(增,删,查,改)
- 各种图的创建以及广度,深度优先遍历(临接矩阵存储)
- Spring mvc绑定日期参数的最佳解决方案
- 条件注释判断浏览器
- protobuf中会严重影响时间和空间损耗的地方
- 华南农业大学形势与政策3
- 陈怡暖:(午评)金银美元齐跌,初请数据助阵
- poj 3009 Curling 2.0 【dfs经典题目】
- 获取任意两个数之间多个随机数的方法;
- 基于jQuery弹出层图片动画查看代码
- 有关NDES管理帐号及用户帐号权限
- oracle函数
- 在android上面让TextView 过多的文字实现有滚动条 scrollview
- 招人 招人 渗透测试 无线安全研究方向
- 使用 ftrace 调试 Linux 内核 (一)