您的位置:首页 > 其它

POJ 3304 Segments 线段交

2013-10-24 22:26 411 查看
计算几何入门

将所有的线段的端点存起来,枚举任意两个端点构成的直线,看是否能穿过所有线段即可

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <cstdlib>
#include <cmath>
#include <map>
#include <sstream>
#include <queue>
#include <vector>
#define MAXN 100005
#define MAXM 211111
#define eps 1e-8
#define INF 500000001
using namespace std;
inline int dblcmp(double d)
{
if(fabs(d) < eps) return 0;
return d > eps ? 1 : -1;
}
struct point
{
double x, y;
point(){}
point(double _x, double _y): x(_x), y(_y) {}
void input()
{
scanf("%lf%lf", &x, &y);
}
bool operator ==(point a)const
{
return dblcmp(a.x - x) == 0 && dblcmp(a.y - y) == 0;
}
point sub(point p)
{
return point(x - p.x, y - p.y);
}
double det(point p)
{
return x * p.y - y * p.x;
}

}p[3333];
struct line
{
point a, b;
line(){}
line(point _a, point _b){ a = _a; b = _b;}
void input()
{
a.input();
b.input();
}
int linecrossseg(line v)//v is seg
{
int d1 = dblcmp(b.sub(a).det(v.a.sub(a)));
int d2 = dblcmp(b.sub(a).det(v.b.sub(a)));
if ((d1 ^ d2) == -2) return 2;
return (d1 == 0 || d2 == 0);
}

};
int n;
int main()
{
int T;
scanf("%d", &T);
while(T--)
{
scanf("%d", &n);
for(int i = 0; i < n; i++) p[2 * i].input(), p[2 * i + 1].input();
int ok = 0;
for(int i = 0; i < 2 * n; i++)
for(int j = i + 1; j < 2 * n; j++)
{
if(p[i] == p[j]) continue;
int flag = 1;
line v = line(p[i], p[j]);
for(int k = 0; k < 2 * n; k += 2)
{
line seg = line(p[k], p[k + 1]);
if(v.linecrossseg(seg) == 0)
{
flag = 0;
break;
}
}
if(flag)
{
ok = 1;
break;
}
}
if(ok || n == 1 || n == 2) puts("Yes!");
else puts("No!");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: