建图

这个题目就是一个 建图

题目链接:点击打开链接

这个题目我也没有什么思路,就是参考别人的博客写的

这里面有一个实验,叫跨立实验,结果就是:判断两直线是否相交,假设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;
}
其实对于这种代码这么长的题目,过程·这么复杂的题目,我肯定不会去去做,果然没有人做,也确实比较难了一点,这个题目叫就先这样吧。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值