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 }

 

posted @ 2018-09-29 10:49  _努力努力再努力x  阅读(260)  评论(0编辑  收藏  举报