蓝桥杯2024年第十五届省赛真题-数字接龙
题目链接
思路:
①经过格子的顺序
②图中不可以出现交叉的路线
③DFS函数中对路径长度的判断:return path.size() == n*n-1; 当它们相等时,棋盘上的每个格子恰好都经历过一次(仅一次)。
DFS代码:
#include<bits/stdc++.h>
using namespace std;
const int N = 20;
int n, k, g[N][N];
string path; //答案
//st记录这个点有没有访问 edge记录是否出现交叉的线路
bool st[N][N], edge[N][N][N][N];
//向量数组
int dx[] = {-1,-1,0,1,1,1,0,-1};
int dy[] = {0,1,1,1,0,-1,-1,-1};
bool dfs(int x1, int y1){
if(x1 == n-1 && y1 == n-1){
//判断了棋盘上的格子是否都恰好经过一次(仅一次)
return path.size() == n*n-1;
}
//标记访问点
st[x1][y1] = true;
for(int i = 0; i <= 7; i++){
int a = dx[i]+x1, b = dy[i]+y1;
//超出范围
if(a<0||b<0||a>=n||b>=n)continue;
//按照格子顺序访问
if(g[a][b] != (g[x1][y1]+1) % k)continue;
//判断是否重复访问
if(st[a][b])continue;
//判断是否交叉
if(i % 2 && (edge[x1][b][a][y1] || edge[a][y1][x1][b]))continue;
edge[x1][y1][a][b] = true;
path += i+'0';
// path.push_back(i+'0');
if(dfs(a, b)) return true;
path.pop_back();
edge[x1][y1][a][b] = false;
}
st[x1][y1] = false;
return false;
}
int main(){
//读入
cin >> n >> k;
for(int i = 0; i<n; i++){
for(int j = 0; j<n; j++){
cin >> g[i][j];
}
}
//暴搜
if(!dfs(0, 0)) cout << "-1" << endl;
else{
for(auto x:path){
cout << x ;
}
}
return 0;
}