八数码问题,IDA*解~

View Code
1 #include <cstdio>
2 #include <cstring>
3 #include <algorithm>
4
5  using namespace std;
6
7  const int SIZE = 365000;
8 const int LEN = 10;
9 const int move[][5] = {{2,3,1},{3,4,0,2},{2,5,1},{3,6,4,0},{4,7,3,5,1},{3,8,4,2},{2,7,3},{3,6,8,4},{2,7,5}};
10 const char moves[][8] = {"dr","dlr","dl","dru","dlru","dlu","ru","lru","lu"};
11 const int DIST[][LEN] =
12 {
13 {0,1,2,1,2,3,2,3,4},
14 {1,0,1,2,1,2,3,2,3},
15 {2,1,0,3,2,1,4,3,2},
16 {1,2,3,0,1,2,1,2,3},
17 {2,1,2,1,0,1,2,1,2},
18 {3,2,1,2,1,0,3,2,1},
19 {2,3,4,1,2,3,0,1,2},
20 {3,2,3,2,1,2,1,0,1},
21 {4,3,2,3,2,1,2,1,0}
22 };
23
24 char org[LEN];
25 char des[LEN];
26
27 char output[SIZE];
28
29 int maxstep;
30
31 int Estimate(char * key)
32 {
33 int value = 0;
34 for (int i = 0;i < LEN - 1;i++)
35 if (key[i] != '0')
36 value += DIST[i][strchr(des,key[i])-des];
37 return value;
38 }
39
40 bool IDAstar(int now,int pos,int pre)
41 {
42 int need = Estimate(org);
43 if (now + need > maxstep) return false;
44
45 if (need == 0)
46 {
47 printf("%d\n",now);
48 output[now] = '\0';
49 printf("%s\n",output);
50 return true;
51 }
52
53 for (int i = 1;i <= move[pos][0];i++)
54 {
55 int npos = move[pos][i];
56
57 if (npos == pre) continue;
58
59 swap(org[pos],org[npos]);
60 output[now] = moves[pos][i-1];
61 if (IDAstar(now + 1,npos,pos)) return true;
62 swap(org[pos],org[npos]);
63 }
64 return false;
65 }
66
67 int main()
68 {
69 //freopen("1.in","r",stdin);
70 //freopen("out.txt","w",stdout);
71
72 int cas;
73 int idx;
74
75 scanf("%d",&cas);
76
77 for (int cc = 0;cc < cas;cc++)
78 {
79 scanf("%s",org);
80 for (int i = 0;i < LEN - 1;i++)
81 if (org[i] == 'X')
82 {
83 idx = i;
84 org[i] = '0';
85 }
86
87 scanf("%s",des);
88 for (int i = 0;i < LEN - 1;i++)
89 if (des[i] == 'X')
90 des[i] = '0';
91
92 printf("Case %d: ",cc + 1);
93
94 for (maxstep = Estimate(org);;maxstep++)
95 if (IDAstar(0,idx,-1))
96 break;
97 }
98 return 0;
99 }