您的位置:首页 > 其它

POJ 1556 The Doors 最短路floyd + 判断两线段相交

2013-08-29 10:34 453 查看
构建模型非常重要。

建图:把起点,终点,每个墙上的4个点分别看成图的顶点;

把这些点中各对点连起来,如果与墙相交(判断两线段相交)则不连,然后floyd暴力一下。

 

思路想到了就蛮清晰的,但我刚学计算几何,一直很纠结点写成结构体还是分开来写,调用的时候哪个比较方便,总觉得2个都很麻烦,诶,所以荒废了比较多的时间,以后不能这么2了。

 

然后我把2种都写了一遍,写计算几何一定要注意规范。

 

代码1:(函数调入点用double)




View Code

#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
#define eps 10e-8
#define inf 1<<29
using namespace std;
struct point
{
double x, y;
};

int n;
double xx[22], yy[22][5];
point p[90];
double adj[90][90];
int psize;

double ff(double x)
{
return x*x;
}
double dis(point p1, point p2)
{
return sqrt(ff(p1.x - p2.x) + ff(p1.y - p2.y));
}
double cross(double x1, double y1, double x2, double y2, double x3, double y3)
{
return (x2 - x1)*(y3 - y1) - (y2 - y1)*(x3 - x1);
}
bool judge(point p1, point p2)
{
if(p1.x >= p2.x)return 0;
int i = 0;
while(xx[i] <= p1.x && i < n)i++;
while(xx[i] < p2.x && i < n)
{
if(cross(p1.x, p1.y, p2.x, p2.y, xx[i], 0)*cross(p1.x, p1.y, p2.x, p2.y, xx[i], yy[i][1])<0
||cross(p1.x, p1.y, p2.x, p2.y, xx[i], yy[i][2])*cross(p1.x, p1.y, p2.x, p2.y, xx[i], yy[i][3])<0
||cross(p1.x, p1.y, p2.x, p2.y, xx[i], yy[i][4])*cross(p1.x, p1.y, p2.x, p2.y, xx[i], 10)<0)
return 0;
i++;
}
return 1;
}
void floyd()
{
int i, j, k;
for(k=0;k<psize;k++)
for(i=0;i<psize;i++)
for(j=i+1;j<psize;j++)
if(i!=k && j!=k)
adj[i][j]=min(adj[i][j], adj[i][k] + adj[k][j]);
printf("%.2f\n",adj[0][psize - 1]);
}
int main()
{
int i, j;
while(~scanf("%d",&n)&&n!=-1)
{
p[0].x = 0; p[0].y = 5;psize=1;
for(i=0;i<n;i++)
{
scanf("%lf",&xx[i]);
for(j=1;j<=4;j++)
{
p[psize].x = xx[i];
scanf("%lf",&p[psize].y);
yy[i][j] = p[psize].y;
psize++;
}
}
p[psize].x = 10; p[psize].y = 5;
psize++;
for(i=0;i<psize;i++)
for(j=0;j<psize;j++)
adj[i][j] = inf;
for(i=0;i<psize;i++)
for(j=i+1;j<psize;j++)
if(judge(p[i], p[j]))
adj[i][j] = dis(p[i], p[j]);
floyd();
}
return 0;
}


代码2:(函数调入点用point)




View Code

#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
using namespace std;
#define inf 1<<29
#define eps 10e-8
#define f(x) (x)*(x)
struct point
{
double x, y;
};

double xx[22], yy[22][5];
double adj[90][90];
point p[90];
int psize;
int n;

double dis(point p1, point p2)
{
return sqrt(f(p1.x - p2.x) + f(p1.y  -p2.y));
}

double cross(point p0,point p1, point p2)//叉积
{
return (p1.x - p0.x)*(p2.y - p0.y) - (p1.y - p0.y)*(p2.x - p0.x);
}

bool line_cross(point p1, point p2, point p3, point p4)//判断两线段相交
{
if(cross(p1, p2, p3)*cross(p1, p2, p4) > eps)return 0;
return 1;
}

bool judge(point p1, point p2)
{
if(p1.x >= p2.x)return 0;
int i = 1;
while(xx[i] <= p1.x && i <= n)i++;
while(xx[i] < p2.x && i <= n)
{
point pp1, pp2, pp3, pp4, pp5, pp6;
pp1.x = pp2.x = pp3.x = pp4.x = pp5.x = pp6.x = xx[i];
pp1.y = 0; pp2.y = yy[i][1]; pp3.y = yy[i][2]; pp4.y = yy[i][3]; pp5.y = yy[i][4];pp6.y = 10;
if(line_cross(p1, p2, pp1, pp2) || line_cross(p1, p2, pp3, pp4) || line_cross(p1, p2, pp5, pp6))
return 0;
i++;
}
return 1;
}

void floyd()
{
int i, j, k;
for(k=0;k<psize;k++)
for(i=0;i<psize;i++)
for(j=i+1;j<psize;j++)
if(k!=i && k!=j)
adj[i][j] = min (adj[i][j], adj[i][k] + adj[k][j]);
printf("%.2f\n", adj[0][psize-1]);
}

int main()
{
int i, j;
while(~scanf("%d",&n) && n != -1)
{
p[0].x = 0; p[0].y = 5;psize=1;
for(i=1;i<=n;i++)
{
scanf("%lf",&xx[i]);
for(j=1;j<=4;j++)
{
p[psize].x = xx[i];
scanf("%lf",&yy[i][j]);
p[psize].y = yy[i][j];
psize++;
}
}
p[psize].x = 10; p[psize].y = 5;psize++;
for(i = 0;i < psize; i++)
for(j = 0;j < psize; j++)
adj[i][j] = inf;
for(i=0;i<psize;i++)
for(j=i+1;j<psize;j++)
if(judge(p[i], p[j]))
adj[i][j] = dis(p[i], p[j]);
floyd();
}
return 0;
}


 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: