数字接龙(蓝桥杯)

本文介绍了使用深度优先搜索(DFS)解决一款名为《数字接龙》的游戏路径问题,遵循特定数字序列和无交叉路径要求。

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

数字接龙

【问题描述】

小蓝最近迷上了一款名为《数字接龙》的迷宫游戏,游戏在一个大小为N × N 的格子棋盘上展开,其中每一个格子处都有着一个 0 . . . K − 1 之间的整数。游戏规则如下:

  1. 从左上角 (0, 0) 处出发,目标是到达右下角 (N − 1, N − 1) 处的格子,每一步可以选择沿着水平/垂直/对角线方向移动到下一个格子。
  2. 对于路径经过的棋盘格子,按照经过的格子顺序,上面的数字组成的序列要满足:0, 1, 2, . . . , K − 1, 0, 1, 2, . . . , K − 1, 0, 1, 2 . . . 。
  3. 途中需要对棋盘上的每个格子恰好都经过一次(仅一次)。
  4. 路径中不可以出现交叉的线路。例如之前有从 (0, 0) 移动到 (1, 1),那么再从 (1, 0) 移动到 (0, 1) 线路就会交叉。

为了方便表示,我们对可以行进的所有八个方向进行了数字编号,如下图2 所示;因此行进路径可以用一个包含 0 . . . 7 之间的数字字符串表示,如下图 1是一个迷宫示例,它所对应的答案就是:41255214。
在这里插入图片描述

现在请你帮小蓝规划出一条行进路径并将其输出。如果有多条路径,输出字典序最小的那一个;如果不存在任何一条路径,则输出 −1。

【输入格式】
第一行包含两个整数 N、K。
接下来输入 N 行,每行 N 个整数表示棋盘格子上的数字。
【输出格式】
输出一行表示答案。如果存在答案输出路径,否则输出 −1。
【样例输入】

3 3
0 2 0
1 1 1
2 0 2

【样例输出】

41255214

【样例说明】
行进路径如图 1 所示。
【评测用例规模与约定】
对于 80% 的评测用例:1 ≤ N ≤ 5。
对于 100% 的评测用例:1 ≤ N ≤ 10,1 ≤ K ≤ 10。

解题思路

题目分析:

  1. 从左上角 (0, 0) 处出发,目标是到达右下角 (N − 1, N − 1) 处的格子,每一步可以选择沿着水平/垂直/对角线方向移动到下一个格子。
  2. 对于路径经过的棋盘格子,按照经过的格子顺序,上面的数字组成的序列要满足:0, 1, 2, . . . , K − 1, 0, 1, 2, . . . , K − 1, 0, 1, 2 . . . 。
  3. 途中需要对棋盘上的每个格子恰好都经过一次(仅一次)。
  4. 如果有多条路径,输出字典序最小的那一个
  5. 路径中不可以出现交叉的线路。例如之前有从 (0, 0) 移动到 (1, 1),那么再从 (1, 0) 移动到 (0, 1) 线路就会交叉。

解题思路:

  1. 因为题目的数据范围较小,所以可以使用DFS,移动方向为8个方向
int dx[] = {
   -1, -1, 0, 1, 1, 1, 0, -1};
int dy[] = {
   0, 1, 1, 1, 0, -1, -1, -1};
  1. 我们需要保证遍历顺序为0, 1, 2, . . . , K − 1, 0, 1, 2, . . . , K − 1, 0, 1, 2 . . .
g[x][y] == k - 1 && g[tx][ty] == 0) || g[tx][ty] == g[x][y] + 1

g[x][y] == k - 1 && g[tx][ty] == 0 || g[tx][ty] == g[x][y] + 1:这是一个复合条件,用于检查当前格子 (x, y) 的值与目标格子 (tx, ty) 的值之间的关系是否满足游戏规则。具体来说:

  • g[x][y] == k - 1 && g[tx][ty] == 0:如果当前格子的值等于 k - 1(即棋盘上数字的最大值),则目标格子的值必须为 0,这样才能保证数字序列的循环性。
  • ||:逻辑或操作符,用于连接上述条件和下面的条件。两者满足一个即可
  • g[tx][ty] == g[x][y] + 1:如果当前格子的值不是 k - 1,则目标格子的值必须比当前格子的值大 1,这样才能保证数字序列是递增的。
  1. 设置一个cnt,如果cnt=n*n说明遍历了每个位置
  2. 在遍历8个方向时我们按0、1、2、3、4、5、6、7的顺序遍历就能得到最小字典序,并且用path数组保存,就能把路径输出
  3. 只有走对角线才会发生相交,我们设置一个st数组存储到达每个格子的方向,再进行判断
    在这里插入图片描述
if (i == 1 && (st[x - 1]
### 蓝桥杯 C语言 数字接龙 解题思路 对于蓝桥杯中的数字接龙问题,目标是最少删除一些数字使得剩下的序列形成一个接龙数列。接龙数列定义为前一个数的末位数字与下一个数的第一位相同。 为了找到最优解,在处理这个问题时可以采用动态规划的方法来减少不必要的计算量并提高效率[^1]。具体来说: - 定义状态 `dp[i][j]` 表示从前 i 个字符构成的子串中结尾处最后一位是 j 的最长接龙长度; - 初始化所有 dp 值为 0 或者不可能达到的最大负值; - 遍历整个字符串数组,更新每一个可能的状态转移方程;如果当前考虑的位置 k 和位置 l 可以连接,则有如下关系:`if(s[k].back() == s[l].front()) dp[l][s[l].back()] = max(dp[l][s[l].back()], dp[k][s[k].back()] + 1)`; - 记录最大值作为最终的结果,并通过回溯得到具体的方案。 下面给出一段基于上述逻辑编写的 C 语言代码片段用于解决此问题: ```c #include <stdio.h> #include <string.h> #define MAXN 105 char str[MAXN]; int n, f[MAXN], g[MAXN]; void solve(){ memset(f, 0, sizeof(f)); for(int i=1; i<=n; ++i){ sscanf(str+i-1; j>0; --j){ if(g[j]/10==last_digit && f[j]+1>f[i]){ f[i]=f[j]+1; } } } int res=0; for(int i=1; i<=n; ++i) res=res<f[i]?f[i]:res; printf("%d\n",n-res); } int main(){ scanf("%d%s",&n,str); solve(); return 0; } ``` 这段程序首先读取输入数据,然后利用动态规划算法寻找能够形成的最长接龙链路数量,最后输出需要移除多少个元素才能使剩余部分成为合法的接龙数列。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

命运从未公平

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值