POJ1912_A highway and the seven dwarfs_判断凸包与直线是否相交
2017-11-13 23:25
513 查看
题意
给出 n 个点和若干条直线,每一条直线用两个点的形式给出。对每一条直线,问所有点是不是在这条直线的同一侧。题目保证直线不会经过n个点。思路
首先就有一个特殊情况。因为 n >= 0。当 n <= 1 的时候,可以直接判定为对每一条直线,n个点都在它的同一侧。对于n > 1的情况,显然是求凸包与直线是否相交的问题。这里利用了凸包的一个性质。
对于凸包上相邻的两个点构成的向量的极角,取 [-pi/2, 3/2pi]时,是单调递增的。
求出凸包上边的极角后,
用二分法,找出极角分别大于给出直线的两个方向向量的第一个向量, 这两个向量的起点,就是在垂直于这条直线的方向上距离最远的两个点。
只需要判断这两个点是否在直线的同一侧,就能判断这条直线是不是穿过凸包。
可以画画图理解一下。
链接
http://poj.org/problem?id=1912代码
#include<cstdio> #include<iostream> #include<vector> #include<algorithm> #include<cmath> using namespace std; const int maxn = 1e5 + 10; const double pi = acos(-1.0); struct P{ double x, y; P(){} P(double x, double y): x(x), y(y){} bool operator < (const P &a) const{ if(x != a.x) return x < a.x; return y < a.y; } P operator - (const P &a) const{ return P(x - a.x, y - a.y); } double det(const P &a) const{ return x * a.y - y * a.x; } double angle(){ double angle = atan2(y, x); if(angle < -pi / 2) angle += 2 * pi; return angle; } }; int n; P ps[maxn], qs[maxn]; double angle[maxn]; P p1, p2; int tb; int convex_hull(){ sort(ps, ps + n); int k = 0; for(int i = 0; i < n; ++i){ while(k > 1 && (qs[k-1] - qs[k-2]).det(ps[i] - qs[k-1]) <= 0) --k; qs[k++] = ps[i]; } for(int i = n - 2, t = k; i >= 0; --i){ while(k > t && (qs[k-1]- qs[k-2]).det(ps[i] - qs[k-1]) <= 0) --k; qs[k++] = ps[i]; } return k-1; } inline int getp(double a){ return lower_bound(angle, angle + tb, a) - angle; } bool inter(){ if(n <= 1) return false; int a = getp((p1 - p2).angle()); int b = getp((p2 - p1).angle()); if((p1 - p2).det(qs[a] - p2) * (p1 - p2).det(qs[b] - p2) <= 0) return true; return false; } int main(){ // freopen("in.txt", "r", stdin); scanf("%d", &n); for(int i = 0; i < n; ++i){ scanf("%lf %lf", &ps[i].x, &ps[i].y); } tb = convex_hull(); for(int i = 0; i < tb; ++i){ angle[i] = (qs[i+1] - qs[i]).angle(); } while(scanf("%lf %lf %lf %lf", &p1.x, &p1.y, &p2.x, &p2.y) == 4){ if(inter()) puts("BAD"); else puts("GOOD"); } return 0; }
相关文章推荐
- POJ 1912 A highway and the seven dwarfs(O(log N)求直线与凸包是否相交)
- POJ 1912 A highway and the seven dwarfs (凸包)
- POJ 1912 A highway and the seven dwarfs (凸包&O(logN)判断直线是否与凸包相交)
- poj 1912 A highway and the seven dwarfs
- poj1912 A highway and the seven dwarfs【凸包+二分】
- poj 1410(判断直线是否相交)
- poj 3304 Segments 【判断是否存在一条直线与所有线段相交】
- 判断直线与线段 是否相交 + 加入误差 故需要判断重点 poj 3304 Segments
- POJ - 3304 :Segments__判断直线和线段是否 相交
- UVA 10256 The Great Divide(凸包应用 即凸包+线段相交判定+点是否在凸包内判断)
- POJ 3304 Segments (计算几何、判断直线与线段是否相交)
- poj 3304 判断是否存在一条直线与所有线段相交
- (计算几何step8.1.2.1)POJ 2653 Pick-up sticks(判断一根木棒的上面时候还有其他木棒——判断两条直线是否相交)
- Segments - POJ 3304 (判断直线与线段是否相交)
- poj 3805 Separate Points 判断凸包是否相交,nlogn复杂度
- POJ 3304 Segments(判断线段和直线是否相交)
- POJ 3304 Segments (判断直线和线段是否相交)
- poj 3304 判断是否有与所有线段相交的直线
- POJ 1228 Grandpa's Estate 判断原始凸包是否唯一
- poj 1679 The Unique MST(判断最小生成树是否唯一)