POJ 1912 A highway and the seven dwarfs(O(log N)求直线与凸包是否相交)
来源:互联网 发布:oracle 数据库高可用 编辑:程序博客网 时间:2024/05/02 01:42
A highway and the seven dwarfs
Time Limit: 8000MS Memory Limit: 30000KTotal Submissions: 2454 Accepted: 485Case Time Limit: 3000MS
Description
Once upon a time, there was a land where several families of dwarfs were living. This land was called Dwarfland. Each family lived in one house. Dwarfs were often visiting their friends from the other families. Because the Dwarfland was free of evil, it happened that each dwarf visited each other during some short period of time.
Once, the humans living in countries around Dwarfland decided to build several straight highways. As the humans weren't aware of the dwarfs, some of the planned highways passed through Dwarfland. The dwarfs discovered this and were quite unhappy about it. The dwarfs are very little, and also very slow, so they are unable to cross the highway safely.
The dwarfs managed to get the plans for the highways somehow, and now they need your help. They would like to keep on visiting each other, so they don't like those highways which divide their houses into two non-empty parts. After they find out which highways they don't like, they will magically prevent the humans from building them.
The dwarfs are very little, and cannot reach the keyboard. So they asked for your help.
Task
Given is a number N of points (houses) in the plane and several straight lines (highways). For each given line, your task is to determine whether all N points lie on the same side of the line or not. Your program has to output the answer for the currently processed line before reading the description of the next one. You may assume that no highway passes through any of the houses.
Once, the humans living in countries around Dwarfland decided to build several straight highways. As the humans weren't aware of the dwarfs, some of the planned highways passed through Dwarfland. The dwarfs discovered this and were quite unhappy about it. The dwarfs are very little, and also very slow, so they are unable to cross the highway safely.
The dwarfs managed to get the plans for the highways somehow, and now they need your help. They would like to keep on visiting each other, so they don't like those highways which divide their houses into two non-empty parts. After they find out which highways they don't like, they will magically prevent the humans from building them.
The dwarfs are very little, and cannot reach the keyboard. So they asked for your help.
Task
Given is a number N of points (houses) in the plane and several straight lines (highways). For each given line, your task is to determine whether all N points lie on the same side of the line or not. Your program has to output the answer for the currently processed line before reading the description of the next one. You may assume that no highway passes through any of the houses.
Input
Your program is supposed to read the input from the standard input and write its output to the standard output. The first line of the input contains one integer N ( 0 < = N < = 100 000). N lines follow, the i-th of them contains two real numbers xi, yi ( -109 < = xi, yi < = 109) separated by a single space - the coordinates of the i-th house.
Each of the following lines contains four real numbers X1, Y1, X2, Y2 ( -109 < = X1, Y1, X2, Y2 < = 109) separated by a single space. These numbers are the coordinates of two different points [X1, Y1] and [X2, Y2], lying on the highway.
Each of the following lines contains four real numbers X1, Y1, X2, Y2 ( -109 < = X1, Y1, X2, Y2 < = 109) separated by a single space. These numbers are the coordinates of two different points [X1, Y1] and [X2, Y2], lying on the highway.
Output
For each line of input, your program is supposed to output a line containing the string "GOOD" if all of the given points are on the same side of the given line, or "BAD" if the given line divides the points.
Sample Input
40.0 06.00 -0.0013.125 4.7474.747 0.475 3 7 04 -4.7 7 4.74 47 4 94
Sample Output
GOODBADBAD
Hint
Huge input,scanf is recommended.
Source
CEOI 2002
题目大意:
有N个点,每次输入两点,确定一条直线,问这条直线是否把这些点分成两部分。
解题思路:
很明显,我们需要先用着N个点构成一个凸包,再判断这条直线是否与凸包相交即可。
开始用O(N)的暴力方法判断相交竟然TLE了。后来看了大神的题解才知道有O(log N)的判断方法。
AC代码:
#include <iostream>#include <algorithm>#include <cstring>#include <cstdio>#include <vector>#include <cmath>using namespace std;#define eps 1e-10const double PI=acos(-1.0);const int maxn=100000+3;int N;double as[maxn];//保存极角//考虑误差的加法运算double add(double a,double b){ if(abs(a+b)<eps*(abs(a)+abs(b))) return 0; return a+b;}int sgn(double x){ if(fabs(x) < eps)return 0; if(x < 0)return -1; else return 1;}//二维向量结构体struct P{ double x,y; P(){} P(double x,double y):x(x),y(y){} P operator+(const P &p) { return P(add(x,p.x),add(y,p.y)); } P operator -(const P &b)const { return P(x - b.x,y - b.y); } P operator*(double d) { return P(x*d,y*d); } //叉积 double operator ^(const P &b)const { return x*b.y - y*b.x; } //点积 double operator *(const P &b)const { return x*b.x + y*b.y; } //绕原点旋转角度B(弧度值),后x,y的变化 void transXY(double B) { double tx = x,ty = y; x = tx*cos(B) - ty*sin(B); y = tx*sin(B) + ty*cos(B); }}ps[maxn];//字典序比较bool cmp_x(const P &p,const P &q){ if(p.x!=q.x) return p.x<q.x; return p.y<q.y;}//求凸包vector<P> convex_hull(P *ps,int n){ sort(ps,ps+n,cmp_x); int k=0;//凸包的顶点数 vector<P> qs(n*2);//构造中的凸包 //构造凸包下侧 for(int i=0;i<n;++i) { while(k>1&&((qs[k-1]-qs[k-2])^(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])^(ps[i]-qs[k-1]))<=0) --k; qs[k++]=ps[i]; } qs.resize(k-1); return qs;}inline double normalize(double r)//把极角转换为[-PI/2,3*PI/2){ if (r < -PI / 2.0 + eps) r += PI * 2; return r;}inline double atan2(const P& p){ return normalize(atan2(p.y, p.x));}int main(){ scanf("%d",&N); for(int i=0;i<N;++i) scanf("%lf%lf",&ps[i].x,&ps[i].y); vector<P> qs; int n=0; if(N>1) { qs=convex_hull(ps,N); n=qs.size(); qs.push_back(qs[0]); } for(int i=0;i<n;++i) as[i]=atan2(qs[i+1]-qs[i]); sort(as,as+n); P p1,p2; while(~scanf("%lf%lf%lf%lf",&p1.x,&p1.y,&p2.x,&p2.y)) { if(N<2)//N小于2特判否则会RE { puts("GOOD"); continue; } int i=upper_bound(as,as+n,atan2(p1-p2))-as;//直线两侧各找一点,若两点在直线两侧,则直线一定分割凸包 int j=upper_bound(as,as+n,atan2(p2-p1))-as; puts(((((p2-p1)^(qs[i]-p1))*((p2-p1)^qs[j]-p1))>-eps)?"GOOD":"BAD"); } return 0;}
0 0
- POJ 1912 A highway and the seven dwarfs(O(log N)求直线与凸包是否相交)
- POJ 1912 A highway and the seven dwarfs (凸包&O(logN)判断直线是否与凸包相交)
- poj1912:A highway and the seven dwarfs(凸包)
- POJ1912_A highway and the seven dwarfs_判断凸包与直线是否相交
- poj1912 A highway and the seven dwarfs【凸包+二分】
- POJ 1912 A highway and the seven dwarfs 已翻译
- Snow White and the Seven Dwarfs
- poj 3304 Segments(贪心+直线是否与线段相交!)
- POJ 1584 A Round Peg in a Ground Hole(点到直线距离,圆与多边形相交,多边形是否为凸)
- URAL 1243. Divorce of the Seven Dwarfs
- URAL 1243 Divorce of the Seven Dwarfs
- POJ 3304 Segments (计算几何、判断直线与线段是否相交)
- poj 1410 Intersection (判两直线是否相交)
- POJ 3304 Segments(判断线段和直线是否相交)
- POJ 1269 Intersecting Lines(直线相交判断,求交点)
- POJ 1269 判断直线与直线相交
- 51nod 判断线段是否相交 poj Segments直线与多条线段相交
- poj 1410(判断直线是否相交)
- 并查集学习入门到熟悉
- 排序算法——快速排序
- Spring MVC简介
- HDU 1285 确定比赛名次(拓扑排序)
- Java进阶(三十九)Java集合类的排序,查找,替换操作
- POJ 1912 A highway and the seven dwarfs(O(log N)求直线与凸包是否相交)
- key-value数据库的一种实现
- linux学习第五篇:安装nginx
- qsort与sort的七种用法!
- 使用HTML5技术控制电脑或手机上的摄像头
- ※ Leetcode - Binary Search - 153. Find Minimum in Rotated Sorted Array(二分查找)
- CodeForces 501B Misha and Changing Handles(STL map)
- CSS属性(1)——writing-mode属性和direction属性
- springmvc学习整理(一) springmvc的基本配置