失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > 10422 - Knights in FEN(迭代深度搜索)

10422 - Knights in FEN(迭代深度搜索)

时间:2021-11-10 05:33:30

相关推荐

10422 - Knights in FEN(迭代深度搜索)

题目:10422 - Knights in FEN

题目大意:5 * 5的棋盘上摆好了旗子,旗子是按照马走日的规则来的,问能在十步之内将起始的棋盘变成题目所给的棋盘那样吗?可以输出最少步数,不可以就输出不行。

解题思路:这题之前我是想着用bfs,但是那个时候判重的时候没有想到用STL的map,用哈希不太会,直接开数组判重又太大了,用map<string, int>来记录一个棋盘的状态(之前没有想到),后来看了别人的代码,发现可以用迭代dfs,因为这题只需要判断十步内的情况,这样题目所给的时间还算是有余的,因为迭代dfs()比广搜要慢。

思路是:每次限定一个深度来进行深搜,这样就不会死循环,并且这个深度就是要求的步数。每限制一个深度就需要重头开始搜索一遍,这样比较花时间。但是节约了空间。这题的马只能跳到空格上,所以就重空格开始,按照规则构造棋盘,注意每次返回的时候都要返回原来的那个状态。这里代码里还参照了别人的剪枝的思想,提前判断一下现在这个状态要到达目标状态最少还要走多少步,如果现在的步数加上还要走的步数超过限定的深度,就可以直接返回了。还有要注意可以不移动就到达目标状态的情况。

#include<stdio.h>#include<string.h>const int M = 5;int t, deep;char finish[M][M];const char init[M][M] = {{'1', '1', '1', '1', '1'},{'0', '1', '1', '1', '1'},{'0', '0', ' ', '1', '1'},{'0', '0', '0', '0', '1'},{'0', '0', '0', '0', '0'}};const int dx[] = {-2, -1, 1, 2, 2, 1, -1, -2};const int dy[] = {-1, -2, -2, -1, 1, 2, 2, 1};int cut() {int sum = 0;for(int i =0; i < M; i++)for(int j = 0; j < M; j++)sum += (finish[i][j] != init[i][j]);return sum / 2;}int dfs(int d, int x, int y) {if(d > deep)return 0;if(memcmp(finish, init, sizeof(init)) == 0)return 1;if(d + cut() > deep)return 0;for(int i = 0; i < 8; i++){int nx = x + dx[i];int ny = y + dy[i];if(nx >= 0 && nx < M && ny >= 0 && ny < M){int swap;swap = finish[x][y];finish[x][y] = finish[nx][ny];finish[nx][ny] = swap;if(dfs(d + 1, nx, ny))return 1;else{swap = finish[x][y];finish[x][y] = finish[nx][ny];finish[nx][ny] = swap;}}}return 0;}int main(){scanf("%d%*c", &t);while(t--){int i, j, x, y;for(i = 0; i < M; i++){for(j = 0; j < M; j++){scanf("%c", &finish[i][j]);if(finish[i][j] == ' '){x = i;y = j;}}getchar();}for(deep = 0; deep < 11; deep++)if(dfs(0, x, y))break;if(deep != 11)printf("Solvable in %d move(s).\n", deep);elseprintf("Unsolvable in less than 11 move(s).\n");}return 0;}

如果觉得《10422 - Knights in FEN(迭代深度搜索)》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。