您的位置:首页 > 其它

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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: