这个题目就是一个 建图
题目链接:点击打开链接
这个题目我也没有什么思路,就是参考别人的博客写的
这里面有一个实验,叫跨立实验,结果就是:判断两直线是否相交,假设p1p2横跨q1q2
则这里有一个结论, 如果[(p1.x-q1.x)*(q2.y-q1.y)]-(p1.y-q1.y)*(q2.x-q1.x)]*[(q2.x-q1.x)*(p2.y-q1.y)-(q2.y-q1.y)*(p2.x-q1.x)]>0
就说明他们是相交的(当然这只在本例题中成立,如果单纯的让你判定是否相交光这一个判断条件是不够的,还有一个排斥实验:http://wenku.baidu.com/link?url=f78DObG55Cnpn9ZVWMQ8sy5Px0-QxW7J-SnaUshmtSKGSYJGPTTkkfSwy9VJJa9GoKC4QfiKfSjXZBQsCB72Fj-CEjT1vfUsEoDNi0Mq8Qu)
下面上例题:http://poj.org/problem?id=1556
代码:
#include<iostream>
#include<cmath>
#include<cstdio>
#include<cstring>
#define inf 0x3f3f3f3f
using namespace std;
int n;
double x,y22,y2,y3,y4;
struct Point
{
double x,y;
//这边有问题
// Point(double,double) {}
// Point()
// {
// x=y=0;
// }
//构造函数
//这个构造函数有什么用呢
};
double xx[28];
Point point[180];
double map[180][180];
double dis(Point a,Point b)
{
return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
//计算两点之间的距离
int intersect(Point a,Point b,Point c)
{
double x111=c.x-a.x;
double y111=c.y-a.y;
double x222=b.x-a.x;
double y222=b.y-a.y;
// printf("%lf\n",x111*y222-x222*y111);
if(x111*y222-x222*y111>0)return 1;
else if(x111*y222-x222*y111<0)return -1;
else return 0;
}
//这一步是什么意思(这个就是判断相交的一个条件)
int judge(Point a,Point b)
{
//x值相等不需要判断。
if(a.x==b.x)return 0;
int i=0;
Point l,r;
// 这里直接定义了,但是可以直接定义的。这个和那个没有什么关系吧
while(xx[i]<=a.x)i++;
// 确定第几列?????
// 后面又加了一下,所以这个是比原来的多了一列
while(xx[i]<b.x)
{
l.x=xx[i];
l.y=0;
r.x=xx[i];
r.y=10;
// 起点后面的那一列的上下限
//Point(xx[i],0) ?? //4*i 4忘记写
if(intersect(a,b,l)*intersect(a,b,point[4*i+1]) <0
|| intersect(a,b,point[4*i+2])*intersect(a,b,point[4*i+3]) <0
|| intersect(a,b,point[4*i+4])*intersect(a,b,r) <0 )
// 这里没有等于零,因为就不可能相交
// 好像明白了一点
// 跨立实验模板
{
// printf("%lf\n",point[4*i+1].x);
// printf("%d\n",intersect(a,b,point[4*i+1]));
// printf("%lf %lf %lf %lf\n",a.x,a.y,b.x,b.y);
return 0;
}
i++;
}
return 1;
}
//这一步是什么意思(这一步是判断相交)
void floyd()
{
for(int k=0; k<=4*n+1; k++)
for(int i=0; i<=4*n+1; i++)
for(int j=0; j<=4*n+1; j++)
{
map[i][j]=min(map[i][j],map[i][k]+map[k][j]);
//map[i][j]>map[i][k]+map[k][j]?map[i][k]+map[k][j]:map[i][j];
}
}
//这个是求最短路
int main()
{
while(scanf("%d",&n))
{
if(n==-1)break;
point[0].x=0;
point[0].y=5;
// 起点初始化
// xx[0]=0;
//double型不能这样初始化
// memset(map,inf,sizeof map);
for(int i=0; i<=4*n+1; i++)
for(int j=0; j<=4*n+1; j++)map[i][j]=999999999;/*初始化*/
for(int i=0; i<n; i++)
{
scanf("%lf%lf%lf%lf%lf",&x,&y22,&y2,&y3,&y4);
xx[i]=point[4*i+1].x=point[4*i+2].x=point[4*i+3].x=point[4*i+4].x=x;
point[4*i+1].y=y22;
point[4*i+2].y=y2;
point[4*i+3].y=y3;
point[4*i+4].y=y4;
}
// 存点
// for(int i=0;i<=4*n+1;i++)
// {
// printf("%lf %lf\n",point[i].x,point[i].y);
// }
xx[n]=10;
// 最后的一个点的x值
point[4*n+1].x=10;
// 最后一个点的x值
point[4*n+1].y=5;
// 最后一个点的y值
for(int i=0; i<=4*n+1; i++)
for(int j=i+1; j<=4*n+1; j++)
{
if(judge(point[i],point[j]))
// 如果不相交,两个点存一下
map[i][j]=dis(point[i],point[j]);
// printf("%lf\n",map[i][j]);
}
// 这个便是构图的要素
floyd();
// 最后最短路,输出一下结果
printf("%.2lf\n",map[0][4*n+1]);
}
return 0;
}
其实对于这种代码这么长的题目,过程·这么复杂的题目,我肯定不会去去做,果然没有人做,也确实比较难了一点,这个题目叫就先这样吧。