主页面:http://www.cnblogs.com/DOLFAMINGO/p/7538588.html
代码一:像BFS那样,把棋盘数组放在结构体中。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cmath> 5 #include <algorithm> 6 #include <vector> 7 #include <queue> 8 #include <stack> 9 #include <map> 10 #include <string> 11 #include <set> 12 #define ms(a,b) memset((a),(b),sizeof((a))) 13 using namespace std; 14 typedef long long LL; 15 const int INF = 2e9; 16 const LL LNF = 9e18; 17 const int MOD = 1e9+7; 18 const int MAXN = 1e6+10; 19 #define AIM 1 //123456789的哈希值为1 20 21 struct node 22 { 23 int s[9]; 24 int loc; 25 }; 26 27 int fac[9] = { 1, 1, 2, 6, 24, 120, 720, 5040, 40320}; 28 int dir[4][2] = { -1,0, 1,0, 0,-1, 0,1 }; 29 char op[4] = {'u', 'd', 'l', 'r' }; 30 31 int cantor(int s[]) //获得哈希函数值 32 { 33 int sum = 0; 34 for(int i = 0; i<9; i++) 35 { 36 int num = 0; 37 for(int j = i+1; j<9; j++) 38 if(s[j]<s[i]) num++; 39 sum += num*fac[8-i]; 40 } 41 return sum+1; 42 } 43 44 int dis_h(int s[]) //获得曼哈顿距离 45 { 46 int dis = 0; 47 for(int i = 0; i<9; i++) 48 if(s[i]!=9) 49 { 50 int x = i/3, y = i%3; 51 int xx = (s[i]-1)/3, yy = (s[i]-1)%3; 52 dis += abs(x-xx) + abs(y-yy); 53 } 54 return dis; 55 } 56 57 char path[100]; 58 bool IDAstar(node now, int depth, int pre, int limit) 59 { 60 if(dis_h(now.s)==0) //搜到123456789 61 { 62 path[depth] = '\0'; 63 puts(path); 64 return true; 65 } 66 67 int x = now.loc/3; 68 int y = now.loc%3; 69 for(int i = 0; i<4; i++) 70 { 71 if(i+pre==1 || i+pre==5) continue; //方向与上一步相反, 剪枝 72 int xx = x + dir[i][0]; 73 int yy = y + dir[i][1]; 74 if(xx>=0 && xx<=2 && yy>=0 && yy<=2) 75 { 76 node tmp = now; 77 tmp.s[x*3+y] = tmp.s[xx*3+yy]; 78 tmp.s[xx*3+yy] = 9; 79 tmp.loc = xx*3+yy; 80 path[depth] = op[i]; 81 if(depth+1+dis_h(tmp.s)<=limit) //在限制内 82 if(IDAstar(tmp, depth+1, i, limit)) 83 return true; 84 } 85 } 86 return false; 87 } 88 89 int main() 90 { 91 char str[50]; 92 while(gets(str)) 93 { 94 node now; 95 int cnt = 0; 96 for(int i = 0; str[i]; i++) 97 { 98 if(str[i]==' ') continue; 99 if(str[i]=='x') now.s[cnt] = 9, now.loc = cnt++; 100 else now.s[cnt++] = str[i]-'0'; 101 } 102 103 int limit; 104 for(limit = 0; limit<=100; limit++) //迭代加深搜 105 if(IDAstar(now, 0, INF, limit)) 106 break; 107 if(limit>100) 108 puts("unsolvable"); 109 } 110 }
代码二:根据DFS的特点,由于棋盘每次只交换一对,所以可以只开一个棋盘数组。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cmath> 5 #include <algorithm> 6 #include <vector> 7 #include <queue> 8 #include <stack> 9 #include <map> 10 #include <string> 11 #include <set> 12 #define ms(a,b) memset((a),(b),sizeof((a))) 13 using namespace std; 14 typedef long long LL; 15 const int INF = 2e9; 16 const LL LNF = 9e18; 17 const int MOD = 1e9+7; 18 const int MAXN = 1e6+10; 19 20 21 int M[100]; 22 int fac[9] = { 1, 1, 2, 6, 24, 120, 720, 5040, 40320}; 23 int dir[4][2] = { -1,0, 1,0, 0,-1, 0,1 }; 24 char op[4] = {'u', 'd', 'l', 'r' }; 25 26 int cantor(int s[]) //获得哈希函数值 27 { 28 int sum = 0; 29 for(int i = 0; i<9; i++) 30 { 31 int num = 0; 32 for(int j = i+1; j<9; j++) 33 if(s[j]<s[i]) num++; 34 sum += num*fac[8-i]; 35 } 36 return sum+1; 37 } 38 39 int dis_h(int s[]) //获得曼哈顿距离 40 { 41 int dis = 0; 42 for(int i = 0; i<9; i++) 43 if(s[i]!=9) 44 { 45 int x = i/3, y = i%3; 46 int xx = (s[i]-1)/3, yy = (s[i]-1)%3; 47 dis += abs(x-xx) + abs(y-yy); 48 } 49 return dis; 50 } 51 52 char path[100]; 53 bool IDAstar(int loc, int depth, int pre, int limit) 54 { 55 int h = dis_h(M); 56 if(depth+h>limit) 57 return false; 58 59 if(h==0) //搜到123456789 60 { 61 path[depth] = '\0'; 62 puts(path); 63 return true; 64 } 65 66 int x = loc/3; 67 int y = loc%3; 68 for(int i = 0; i<4; i++) 69 { 70 if(i+pre==1 || i+pre==5) continue; //方向与上一步相反, 剪枝 71 int xx = x + dir[i][0]; 72 int yy = y + dir[i][1]; 73 if(xx>=0 && xx<=2 && yy>=0 && yy<=2) 74 { 75 swap(M[loc], M[xx*3+yy]); 76 path[depth] = op[i]; 77 if(IDAstar(xx*3+yy, depth+1, i, limit)) 78 return true; 79 swap(M[loc], M[xx*3+yy]); 80 } 81 } 82 return false; 83 } 84 85 int main() 86 { 87 char str[50]; 88 while(gets(str)) 89 { 90 int cnt = 0, loc; 91 for(int i = 0; str[i]; i++) 92 { 93 if(str[i]==' ') continue; 94 if(str[i]=='x') M[cnt] = 9, loc = cnt++; 95 else M[cnt++] = str[i]-'0'; 96 } 97 98 int limit; 99 for(limit = 0; limit<=100; limit++) //迭代加深搜 100 if(IDAstar(loc, 0, INF, limit)) 101 break; 102 if(limit>100) 103 puts("unsolvable"); 104 } 105 }