AcWing 5989. 数字接龙
原题链接
中等
作者:
Phyllis
,
2025-03-31 20:58:21
· 广东
,
所有人可见
,
阅读 10
#include <cstring>
#include <iostream>
using namespace std;
// dfs图搜索 + 剪枝 遍历八个方向
const int N = 12;
string path; // 用字符串存路径
int g[N][N]; // 存地图
bool st[N][N], exg[N][N][N][N]; // st判断是否走过 exg判断是否会交叉
int dx[] = {-1, -1, 0, 1, 1, 1, 0, -1}; // 偏移量数组存八个方向
int dy[] = {0, 1, 1, 1, 0, -1, -1, -1}; // 数组下标就是方向数字
int n, k;
bool dfs(int a, int b)
{
// 走到最后一个格子, 若路径的长度没够说明无解(因为每个格子只能走一次)
if(a == n - 1 && b == n - 1) return path.size() == n * n - 1;
st[a][b] = true; // 标记
// 遍历八个方向
for(int i = 0;i < 8; i++)
{
int x = a + dx[i], y = b + dy[i];
if(x < 0 || x >= n || y < 0 || y >= n) continue; // 出界
if(st[x][y]) continue; // 走过
if(g[x][y] != (g[a][b] + 1) % k) continue; // 路径不符合题目顺序
if(i % 2 &&(exg[a][y][x][b] || exg[x][b][a][y])) continue; //对角线有交叉
// i%2判断是走对角线
exg[a][b][x][y] = true;
path += i + '0'; // 用字符串存就可以直接装换成阿斯克码
if(dfs(x,y)) return true;
path.pop_back(); //
exg[a][b][x][y] = false; // 恢复现场
}
st[a][b] = false; // 恢复现场(对称着写不会忘)
return false;
}
int main()
{
cin >> n >> k;
for(int i = 0; i < n; i ++)
for(int j = 0;j < n; j++)
scanf("%d", &g[i][j]);
if(!dfs(0, 0)) puts("-1");
else cout << path << endl;
//cout << path.size() << n * n - 1 << endl;
return 0;
}