BZOJ 1085 骑士精神 迭代加深搜索+A*
题目链接:
https://www.lydsy.com/JudgeOnline/problem.php?id=1085
题目大意:
在一个5×5的棋盘上有12个白色的骑士和12个黑色的骑士, 且有一个空位。在任何时候一个骑士都能按照骑士的走法(它可以走到和它横坐标相差为1,纵坐标相差为2或者横坐标相差为2,纵坐标相差为1的格子)移动到空位上。 给定一个初始的棋盘,怎样才能经过移动变成如下目标棋盘: 为了体现出骑士精神,他们必须以最少的步数完成任务。
思路:
迭代加深搜索+A*剪枝即可。
每次枚举上限搜索,可以防止dfs每次都要搜到15的深度。
1 #include<bits/stdc++.h> 2 #define IOS ios::sync_with_stdio(false);//不可再使用scanf printf 3 #define Max(a, b) ((a) > (b) ? (a) : (b))//禁用于函数,会超时 4 #define Min(a, b) ((a) < (b) ? (a) : (b)) 5 #define Mem(a) memset(a, 0, sizeof(a)) 6 #define Dis(x, y, x1, y1) ((x - x1) * (x - x1) + (y - y1) * (y - y1)) 7 #define MID(l, r) ((l) + ((r) - (l)) / 2) 8 #define lson ((o)<<1) 9 #define rson ((o)<<1|1) 10 #define Accepted 0 11 #pragma comment(linker, "/STACK:102400000,102400000")//栈外挂 12 using namespace std; 13 inline int read() 14 { 15 int x=0,f=1;char ch=getchar(); 16 while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();} 17 while (ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} 18 return x*f; 19 } 20 typedef long long ll; 21 const int maxn = 2000 + 10; 22 const int MOD = 1000000007;//const引用更快,宏定义也更快 23 const int INF = 1e9 + 7; 24 const double eps = 1e-6; 25 26 int ans[5][5] = 27 { 28 1,1,1,1,1, 29 0,1,1,1,1, 30 0,0,2,1,1, 31 0,0,0,0,1, 32 0,0,0,0,0 33 }; 34 int dir[8][2] = {1,2,1,-2,-1,2,-1,-2,2,1,2,-1,-2,1,-2,-1}; 35 int flag, k; 36 bool judge(int a[5][5]) 37 { 38 for(int i = 0; i < 5; i++)for(int j = 0; j < 5; j++) 39 if(a[i][j] != ans[i][j])return false; 40 return true; 41 } 42 int eva(int a[5][5])//至少还需要走的步数 43 { 44 int tmp = 0; 45 for(int i = 0; i < 5; i++)for(int j = 0; j < 5; j++) 46 if(a[i][j] != ans[i][j])tmp++; 47 return tmp; 48 } 49 void Search(int d, int a[5][5], int x, int y) 50 { 51 if(d == k){flag = judge(a); return;} 52 if(flag)return; 53 for(int i = 0; i < 8; i++) 54 { 55 int xx = x + dir[i][0]; 56 int yy = y + dir[i][1]; 57 if(xx < 0 || xx > 4 || yy < 0 || yy > 4)continue; 58 swap(a[x][y], a[xx][yy]); 59 if(eva(a) + d <= k)Search(d + 1, a, xx, yy); 60 swap(a[x][y], a[xx][yy]); 61 } 62 } 63 int main() 64 { 65 int T; 66 scanf("%d", &T); 67 while(T--) 68 { 69 char Map[10]; 70 int a[5][5]; 71 int x, y; 72 flag = 0; 73 for(int i = 0; i < 5; i++) 74 { 75 scanf("%s", Map); 76 for(int j = 0; j < 5; j++) 77 if(Map[j] == '*')a[i][j] = 2, x = i, y = j; 78 else a[i][j] = Map[j] - '0'; 79 } 80 for(k = 1; k <= 15; k++) 81 { 82 Search(0, a, x, y); 83 if(flag){printf("%d\n", k);break;} 84 } 85 if(!flag)printf("-1\n"); 86 87 } 88 return Accepted; 89 }
越努力,越幸运