Information Transmission-3

博客围绕河南省第十二届大学生程序设计竞赛的一道题目展开。该题是最短路径问题,要求路径不能左转。题目给出了区域内基地坐标、道路信息等输入输出描述。解析部分介绍了判断路径走向的方法,通过向量叉乘判断是否右转,最后提及代码具体实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目描述:

There is n bases in a certain area, numbered 1, 2,. … … , n, the location of base i is represented by coordinates (xi, yi). Dr. Kong is at point (x1, y1), he must send an information to point (xn, yn). Because of the insecurity of the network, he decided to drive the information in person. When he is ready to leave, he find that there is something wrong with the steering wheel of his car. The steering wheel can only turn right and can not turn left. All roads in the area are known . If there is a road from base i to base j, the path length of the road is calculated from the coordinates sqrt((xi-xj)2 +(yi-yj)2) , assuming that all roads are two-way. At first, Dr. Kong may choose any road to set off from base 1. Once he leaves, he can only go straight or turn right at a given coordinate point. For faster transmission of information , Can you help Dr. Kong design a shortest path from Base 1 to Base n without turning left on the steering wheel?

输入描述:

The first line of the input contains one integer T, which is the number of test cases (1<=T<=5). Each test case specifity:

  • Line 1: n m n bases, m roads1≤n≤100,1≤m≤200)
  • Line 2~n+1: xi yi the location of base i ( 2 integers,0≤xi,yi≤1000)
  • Line n+2~n+m+1: ik jk there is a road from base ik to base jk

输出描述:

For each test case generate a single line: a real number, the shortest path from Base 1 to Base n without turning left on the steering wheel. accurate to 2 decimal places.

样例输入:

1
5 6
10 10
10 5
30 5
12 30
15 0
1 2
2 5
3 5
1 3
1 4
4 5

样例输出:

36.43

来源:

河南省第十二届大学生程序设计竞赛

题目解析:

怎么说呢,是一道不算是很复杂的最短路径问题,最为烦躁的地方就在于,每次都要求向右拐,所以要判断是否吻合条件

设p1=(x1,y1), p2=(x2,y2), p3=(x3,y3)

求向量

p12=(x2-x1,y2-y1)

p23=(x3-x2,y3-y2)

则当 p12与 p23 的叉乘(向量积)

p12 x p23 = (x2-x1)(y3-y2)-(y2-y1)(x3-x2)

为正时,p1-p2-p3 路径的走向为逆时针,

为负时,p1-p2-p3 走向为顺时针

为零时,p1-p2-p3 所走的方向不变,亦即三点在一直线上

代码具体实现:

#include<bits/stdc++.h>
using namespace std;
int x[205];
int y[205];
double a[205][205];
double lu[205];
int shangx[205];
int shangy[205];
int visit[205];
int n,m;
double juli(int x1,int x2,int y1,int y2)
{
    return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
}
int dijkstra()
{
    int i;
    for(i=1;i<=n;i++)
    {
        lu[i]=a[i][1];
        shangx[i]=x[1];
        shangy[i]=y[1];
    }
    visit[1]=1;
    lu[1]=0.0;
    for(int j=1;j<n;j++)
    {
        int t;
        double minn=99999.9;
        for(i=1;i<=n;i++)
        {
            if(visit[i]==0&&lu[i]<minn)
            {
                minn=lu[i];
                t=i;
            }
        }
        visit[t]=1;
        for(i=1;i<=n;i++)
        {
            if(visit[i]==0)
            {
                if(lu[i]>lu[t]+a[t][i]&&((x[t]-shangx[t])*(y[i]-y[t])-(y[t]-shangy[t])*(x[i]-x[t]))<=0)
                {
                    lu[i]=lu[t]+a[t][i];
                    shangx[i]=x[t];
                    shangy[i]=y[t];
                }
            }
        }
    }
    printf("%.2lf\n",lu[n]);
}
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        memset(x,0,sizeof(x));
        memset(y,0,sizeof(y));
        memset(visit,0,sizeof(visit));
        memset(shangx,0,sizeof(shangx));
        memset(shangy,0,sizeof(shangy));
        for(int i=0;i<=205;i++)
        {
            for(int j=0;j<=205;j++)
            {
                a[i][j]=999999.0;
            }
        }
        scanf("%d%d",&n,&m);
        int i;
        for(i=1;i<=n;i++)
        {
            scanf("%d%d",&x[i],&y[i]);
        }
        for(i=0;i<m;i++)
        {
            int xx,yy;
            scanf("%d%d",&xx,&yy);
            a[xx][yy]=a[yy][xx]=juli(x[xx],x[yy],y[xx],y[yy]);
        }
        dijkstra();
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值