您的位置:首页 > 其它

POJ 3304(计算几何初步——判断线段和直线相交,加上枚举)

2012-01-11 16:15 525 查看
这题有2点要注意:

一丶当n==1时,应特判输出YES

二丶精度控制,当2点的距离相差小于1E-8,近似看作同一点。

View Code

#include<iostream>
#include<cmath>
#define EPS 1e-8
#define MAXN 104
using namespace std;
struct point {
double x, y;
};
typedef point VECTOR;

struct segment {
point p[2];
}data[MAXN];

bool vis[MAXN];

double cross(point &p1, point &p2)
{
return p2.y*p1.x - p2.x*p1.y;
}

bool equal(point &sp, point &ep)
{
if (sqrt((sp.x - ep.x)*(sp.x - ep.x) + (sp.y - ep.y)*(sp.y - ep.y)) < EPS)return true;
return false;
}

bool check(point &sp, point &ep, int n)
{
for (int i(0); i<n; ++i) {
if (!vis[i]) {
VECTOR fir, sec, thr;
fir.x = data[i].p[0].x - sp.x;
fir.y = data[i].p[0].y - sp.y;
sec.x = ep.x - sp.x;
sec.y = ep.y - sp.y;
thr.x = data[i].p[1].x - sp.x;
thr.y = data[i].p[1].y - sp.y;
if (cross(fir, sec)*cross(sec, thr) < -EPS)return false;
}
}
return true;
}

bool judge(int n)
{
for (int i(0); i<n; ++i) {
vis[i] = true;
for (int num = 0; num<2; ++num) {
for (int j(i+1); j<n; ++j) {
for (int cnt = 0; cnt<2; ++cnt) {
if (!equal(data[i].p[num],data[j].p[cnt])) {
vis[j] = true;
if (check(data[i].p[num],data[j].p[cnt],n))return true;
vis[j] = false;
}
}
}
}
vis[i] = false;
}
return false;
}

int main()
{
int T;
scanf("%d",&T);
while (T--) {
memset(vis,false,sizeof(vis));
int n;
scanf("%d",&n);
for (int i(0); i<n; ++i) {
scanf("%lf%lf%lf%lf",&data[i].p[0].x,&data[i].p[0].y,&data[i].p[1].x,&data[i].p[1].y);
}
if (n == 1) {
cout<<"Yes!\n";
continue;
}
if (judge(n)) {
cout<<"Yes!\n";
} else {
cout<<"No!\n";
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: