蓝桥杯真题(路径)C语言

题目

        小蓝学习了最短路径之后特别高兴,他定义了一个特别的图,希望找到图 中的最短路径。

        小蓝的图由 2021 个结点组成,依次编号 1 至 2021。

对于两个不同的结点 a, b,如果 a 和 b 的差的绝对值大于 21,则两个结点 之间没有边相连;如果 a 和 b 的差的绝对值小于等于 21,则两个点之间有一条 长度为 a 和 b 的最小公倍数的无向边相连。

        例如:结点 1 和结点 23 之间没有边相连;结点 3 和结点 24 之间有一条无 向边,长度为 24;结点 15 和结点 25 之间有一条无向边,长度为 75。

        请计算,结点 1 和结点 2021 之间的最短路径长度是多少。

        提示:建议使用计算机编程解决问题

思路

        题目意思已经很明确了,使用最短路径来解决问题,最短路径有专门的算法,我在这里使用的Dijkstra算法。这道题不只考查最短路径,还涉及到 最小公倍数的查找,在这里使用递归对其进行判断。对数组初始化时,一定要选择一个较大的数,不然比较那里就会出现问题。因为1到2021的最短路径是一个很大的数,注意,注意,注意!

代码

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define inf 1000000000
#define N 3000
#define n 2021
int a[N][N];
int gkd(int b,int z)
{
    if(z==0)
        return b;
    else
        return gkd(z,b%z);
}
void DJ()(Dijkstra算法过程)
{
    int dist[N],visit[N],i,j,k,min,c;
    for(i=1;i<=n;i++)
    {
        dist[i]=a[1][i];
    }
    for(i=1;i<=n;i++)
    {
        visit[i]=0;
    }
    for(i=1;i<=n;i++)
    {
        min=inf;
        for(j=1;j<=n;j++)
        {
            if(visit[j]==0&&dist[j]<min)
            {
                min=dist[j];
                k=j;
            }
        }
        visit[k]=1;
        for(c=1;c<=n;c++)
        {
            if(a[k][c]<inf)
            {
                if(dist[c]>dist[k]+a[k][c])
                {
                    dist[c]=dist[k]+a[k][c];
                }
            }
        }
    }
    printf("%d",dist[n]);
}
int main()
{
    int i,j;
    for(i=1;i<=n;i++)
    {
        for(j=1;j<=n;j++)
        {
            if(i==j)
                a[i][j]=0;
            else
                a[i][j]=inf;
        }
    }
    for(i=1;i<=n;i++)
    {
        for(j=1;j<=n;j++)
        {
            if(i!=j)
            {
                if(abs(i-j)<=21)
                {
                    a[i][j]=i*j/gkd(i,j);(求最小公倍数)
                    a[j][i]=i*j/gkd(i,j);
                }
            }
        }
    }
    DJ();
    return 0;
}

### 关于C语言蓝桥杯比赛学习路径 #### 初期准备(1-3个月) 对于希望参加蓝桥杯并专注于C语言的参赛者来说,在初期应当着重理解掌握C语言的核心概念,包括但不限于指针、内存管理基本的数据结构如数组链表。这些知识点可以通过阅读《C Primer Plus》来深入理解[^2]。 为了更好地巩固所学理论知识,建议完成一些小型实践项目,比如构建一个简易的学生管理系统或是编写简单的文件加密工具。这类项目的实现不仅有助于加深对C语言的理解,还能提高解决实际问题的能力。 此外,在这一阶段还需初步涉猎算法领域,特别是要熟练掌握几种常见的排序方法——冒泡排序与快速排序;熟悉递归的概念及其应用场合;并对动态规划有一个大致的认识。通过研读《算法竞赛入门经典》中的相关内容可以达到上述目标。 #### 中级提升(3-6个月) 当具备了一定的基础之后,则应进一步深化专业知识技术水平: - **高级特性探索**:继续钻研更复杂的主题,像位运算操作、宏定义技巧等; - **数据结构扩展**:除了之前提到过的线性表之外,还要接触栈、队列、树形结构等多种形式的数据存储方式; - **算法强化训练**:加大练习强度,尝试解答更多类型的题目,尤其是那些涉及图论、字符串匹配等方面的内容; - **模拟试题演练**:定期参与往届真题测试,以此检验自身的进步程度,并找出薄弱环节加以改进。 值得注意的是,虽然这里给出的时间框架是一个大概范围,但每个人的学习进度可能有所不同,因此可以根据个人情况灵活调整计划安排。 #### 实战资源推荐 针对想要高效备考的同学而言,利用优质的在线课程也是一种不错的选择。考虑到不同人的需求异较大,可以选择适合自己的平台进行深造。例如,如果偏好Java而遇到合适的机会也可以借鉴其他语言的教学材料作为补充[^1]。不过就C语言本身来讲,“蓝桥云课”提供了专门面向该领域的培训服务,其中不乏许多实用性强且针对性高的教程可供参考。 另外,网络上也有不少热心人士分享了自己积累下来的宝贵资料,其中包括历年来的赛题解析文档以及配套视频讲解等等。例如某位网友上传了一份详细的嵌入式方向复习指南至百度网盘供人下载查阅[^4]。尽管这份资料主要侧重于特定的技术分支,但对于整体编程思维能力的培养仍然具有积极意义。 ```c // 示例代码片段展示如何创建一个简单函数用于计算两个整数之 #include <stdio.h> int add(int a, int b){ return a + b; } int main(){ printf("%d\n",add(3,5)); return 0; } ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值