您的位置:首页 > 其它

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的处理 ,计算几何要注意精度了了!

——————————————————————————————————————————

源代码:

#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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  struct c ini