POJ 3304 Segments
2012-09-27 19:47
239 查看
题目链接:http://poj.org/problem?id=3304
——————————————————————————————————————————
题目描述:
有一堆线段在一个二维空间上,若存在某条直线,使得这些线段在这个直线的投影们至少一个公共交点,输出yes 。若不存在这样的直线,输出no
——————————————————————————————————————————
题目思路:
问题变化为,是否存在一条直线与所有的线段相交。
假设存在这样一条直线,则通过各种平移,总可以使得这个直线与至少两个线段的端点相交。(这是个边界情况,满足了这个情况,交在线段内部的就不用说了~)
于是枚举第一个线段的两个端点,在枚举第二个线段的两个端点。并通过叉积判断经过这两个端点直线是否与所有其他线段都相交。(叉积判左右。)
——————————————————————————————————————————
题目细节:
1、若开始枚举的时候端点重合了,要再找个新的端点来判定。
2、若只有一个点,要特判!
3、不要再忘记把
//freopen("in.in", "r", stdin);
//freopen("out.txt","w",stdout);
去掉了,大姐!!
4、poj只能让g++编译通过,不晓得为啥。
5、注意eps的处理 ,计算几何要注意精度了了!
——————————————————————————————————————————
源代码:
——————————————————————————————————————————
题目描述:
有一堆线段在一个二维空间上,若存在某条直线,使得这些线段在这个直线的投影们至少一个公共交点,输出yes 。若不存在这样的直线,输出no
——————————————————————————————————————————
题目思路:
问题变化为,是否存在一条直线与所有的线段相交。
假设存在这样一条直线,则通过各种平移,总可以使得这个直线与至少两个线段的端点相交。(这是个边界情况,满足了这个情况,交在线段内部的就不用说了~)
于是枚举第一个线段的两个端点,在枚举第二个线段的两个端点。并通过叉积判断经过这两个端点直线是否与所有其他线段都相交。(叉积判左右。)
——————————————————————————————————————————
题目细节:
1、若开始枚举的时候端点重合了,要再找个新的端点来判定。
2、若只有一个点,要特判!
3、不要再忘记把
//freopen("in.in", "r", stdin);
//freopen("out.txt","w",stdout);
去掉了,大姐!!
4、poj只能让g++编译通过,不晓得为啥。
5、注意eps的处理 ,计算几何要注意精度了了!
——————————————————————————————————————————
源代码:
#include <cstdio> #include <iostream> #include <cstring> #include <math.h> using namespace std; #define INF 10000000 #define min(a,b) ((a)>(b)?(b):(a)) #define max(a,b) ((a)>(b)?(a):(b)) #define maxn 110 const double eps = 1e-8; typedef double T; int n = 0; struct Pt { T x; T y; Pt(){} Pt(T px,T py) { x = px; y = py; } Pt &operator +(const Pt &p) const { Pt c; c.x = x + p.x; c.y = y + p.y; return c; } Pt &operator -(const Pt &p) const { Pt c; c.x = x - p.x; c.y = y - p.y; return c; } int operator ==(const Pt &p)const { T temp = 0; temp = sqrt((x - p.x)*(x - p.x)+(y-p.y)*(y-p.y)); if(temp<eps) return 1; else return 0; } }; struct Line { Pt a; Pt b; int cont; Line(){} Line (Pt p1,Pt p2) { a = p1; b = p2; } }line[120]; T dpr(Pt a,Pt b,Pt c) { return (b.x-a.x)*(c.x-a.x)+(b.y-a.y)*(c.y-a.y); } T cpr(Pt a,Pt b,Pt c) //ab * ac { return (b.x-a.x)*(c.y-a.y)-(b.y-a.y)*(c.x-a.x); } bool cmp(Line l1,Line l2) { return l1.a.x < l2.a.x; } int judge(int i, int j ,Pt a,Pt b) { int k = 0,m = -1; if(a == b) { for(k = 0;k<n;k++) { if(k == i || k == j) continue; if(!(line[k].a == a)) { b = line[k].a; m = k; break; } else if(!(line[k].b==a)) { b = line[k].b; m = k; break; } } if(k == n) return 1; } for(k = 0;k<n;k++) { if(k == i || k == j || k == m) continue; if(cpr(a,line[k].a,b)*cpr(a,b,line[k].b)<0) return 0; } return 1; } int main() { //freopen("in.in", "r", stdin); //freopen("out.txt","w",stdout); int t = 0 ,i = 0,j = 0; T x1 = 0,y1 = 0,x2 = 0,y2 = 0; int flag = 0; scanf("%d",&t); while(t--) { scanf("%d",&n); flag = 0; if(n == 1) flag = 1; for(i = 0;i<n;i++) { scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2); line[i] = Line(Pt(x1,y1),Pt(x2,y2)); } for(i = 0;i<n && (flag == 0);i++) for(j = i+1;j<n;j++) { if(judge(i,j,line[i].a,line[j].a) || judge(i,j,line[i].a,line[j].b) \ || judge(i,j,line[i].b,line[j].a) || judge(i,j,line[i].b,line[j].b)) { flag = 1; break; } } if(flag) printf("Yes!\n"); else printf("No!\n"); } return 0; }
相关文章推荐
- 【计算几何】【poj 3304】Segments
- POJ 3304 segments 线段和直线相交
- poj 3304 Segments(计算几何)
- zoj 2870 || poj 3304 Segments
- poj 3304 Segments(判断直线与线段相交)
- poj 3304 Segments
- POJ 3304 Segments 枚举线段端点+判断相交
- poj 3304 Segments
- POJ 3304 Segments --枚举,几何
- poj 3304 Segments
- poj 3304 Segments(线段与直线相交)
- POJ-3304 Segments(计算几何)
- POJ 3304 Segments(计算几何)
- poj 3304 Segments(利用叉积求是否存在直线与所给线段相交)
- poj-3304-Segments
- POJ 3304 Segments 叉积
- poj 3304 Segments 直线 线段求交
- POJ 3304:Segments 计算几何 是否有直线与所有线段相交
- POJ 3304 Segments 线段和直线的交点
- POJ 3304 Segments 【计算几何】【直线和线段的关系】