POJ 3304 Segments 枚举线段端点+判断相交

来源:互联网 发布:cf为什么老是网络异常 编辑:程序博客网 时间:2024/06/11 11:24

题目描述:http://poj.org/problem?id=3304

解题思路:

所有线段在直线上的投影有公共区域,那么这条直线存在一条法线通过所有的线段。如果存在这么一条直线,那么这条直线必定至少通过所有端点中的两个。因为我们总可以移动这条直线使之被线段的端点卡住。所以只需要枚举端点和判断直线与线段相交就行了。


#include "stdio.h"#include "math.h"#define MAXN 107#define eps 1e-8struct point {double x, y;} p[MAXN*4];struct line {struct point a, b;} l[MAXN];int n ,np;bool eql(int i, int j) {if (fabs(p[i].x-p[j].x)<eps && fabs(p[i].y-p[j].y)<eps) return true;else return false;}double xProduct(struct point a, struct point b, struct point c) {double x1 = b.x-a.x, y1 = b.y-a.y;double x2 = c.x-a.x, y2 = c.y-a.y;return (x1*y2 - x2*y1);}bool intersect(int x, int y) {int i;for (i=1; i<=n; i++) {if (xProduct(p[x], p[y], l[i].a) * xProduct(p[x], p[y], l[i].b) > eps) {return false;} }return true;}void init() {double ax, ay, bx, by;int i;scanf("%d", &n);np = 0;for (i=1; i<=n; i++) {scanf("%lf %lf %lf %lf", &ax, &ay, &bx, &by);l[i].a.x = ax; l[i].a.y = ay;l[i].b.x = bx; l[i].b.y = by;++np;p[np].x = ax; p[np].y = ay;++np;p[np].x = bx; p[np].y = by;}}int main() {int i, t, j;bool exist;scanf("%d", &t);while (t--) {exist = false;init();for (i=1; i<=np; i++) for (j=i+1;j<=np; j++) {if (!eql(i, j) && intersect(i, j)) {exist = true;break;}}if (exist) {printf("Yes!\n");} else {printf("No!\n");}}return 0;}

0 0