题目链接不好找:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=1122
用的 IDA*,跑了6.536s,时限是45s(刚看了627个人通过,我是第515名……,排行榜比较恐怖啊,见下图)
这道题的逆序剪枝和八数码不同,具体参考这篇文章:http://mathworld.wolfram.com/15Puzzle.html
1A!
1 # include <stdio.h> 2 # include <math.h> 3 # include <string.h> 4 5 # define MIN(x, y) ((x)<(y) ? (x):(y)) 6 7 # define SIZE 4 8 # define N SIZE*SIZE 9 # define DIR_N 4 10 # define INF 0x7fffffff 11 # define MAX_DEPTH 1000 12 13 char solved; 14 char start[N], goal[N]; 15 char cur[N]; 16 17 int bound; 18 const char md[] = {'U', 'L', 'R', 'D'}; 19 const short int dir[][2] = {{-1,0}, {0,-1}, {0,1}, {1,0}}; 20 char path[MAX_DEPTH]; 21 22 void solve(void); 23 void read(char *s); 24 int IDAstar(void); 25 char inv_judge(char *s); 26 int heu(void); 27 int dfs(int zero_pos, int depth, char direction); 28 29 int main() 30 { 31 int i, T; 32 33 scanf("%d", &T); 34 for (i = 0; i < N-1; ++i) 35 goal[i] = i + 1; 36 goal[N-1] = 0; 37 for (i = 1; i <= T; ++i) 38 { 39 read(start); 40 memcpy(cur, start, N); 41 solve(); 42 } 43 44 return 0; 45 } 46 47 void solve() 48 { 49 int i, depth; 50 51 if (inv_judge(start)) puts("This puzzle is not solvable."); 52 else 53 { 54 memset(path, -1, sizeof(path)); 55 depth = IDAstar(); 56 for (i = 0; path[i]!=-1; ++i) 57 { 58 putchar(md[path[i]]); 59 } 60 putchar('\n'); 61 } 62 } 63 64 void read(char *s) 65 { 66 int i, t; 67 68 for (i = 0; i < N; ++i) 69 { 70 scanf("%d", &t); 71 s[i] = t; 72 } 73 } 74 75 int IDAstar(void) 76 { 77 int i; 78 79 solved = 0; 80 bound = heu(); 81 82 for (i = 0; start[i] && i < N; ++i) ; 83 84 while (!solved && bound<100) 85 { 86 bound = dfs(i, 0, -10); 87 } 88 89 return bound; 90 } 91 92 int dfs(int pos, int depth, char d) 93 { 94 int h, i, nx, ny, npos, nbound, t; 95 96 h = heu(); 97 98 if (depth+h > bound) return depth+h; 99 if (h == 0) 100 { 101 solved = 1; 102 return depth; 103 } 104 105 nbound = INF; 106 for (i = 0; i < DIR_N; ++i) 107 { 108 if (i+d == DIR_N-1) continue; 109 nx = pos/SIZE + dir[i][0]; 110 ny = pos%SIZE + dir[i][1]; 111 if (0<=nx && nx<SIZE && 0<=ny && ny<SIZE) 112 { 113 path[depth] = i; 114 npos = nx*SIZE + ny; 115 cur[pos] = cur[npos]; cur[npos] = 0; /* pos -> npos */ 116 t = dfs(npos, depth+1, i); 117 if (solved) return t; 118 nbound = MIN(nbound, t); 119 cur[npos] = cur[pos]; cur[pos] = 0; 120 } 121 } 122 return nbound; 123 } 124 125 int heu(void) /* return heu(cur_state) */ 126 { 127 char ch; 128 int i, j, ret; 129 130 ret = 0; 131 for (i = 0; i < N; ++i) 132 { 133 ch = goal[i]; 134 if (ch == 0) continue; 135 for (j = 0; j < N; ++j) 136 { 137 if (ch == cur[j]) 138 { 139 ret = ret + abs(i/SIZE-j/SIZE) + abs(i%SIZE-j%SIZE); 140 } 141 } 142 } 143 144 return ret; 145 } 146 147 char inv_judge(char *s) 148 { 149 char ch, ret; 150 int i, j; 151 152 ret = 0; 153 for (i = 0; i < N-1; ++i) 154 { 155 if ((ch = s[i]) == 0 && (i/SIZE+1)&0x1) 156 ret = 1 - ret; 157 for (j = i+1; j < N; ++j) 158 { 159 if (s[j] && s[j]<ch) ret = 1 - ret; 160 } 161 } 162 163 return ret; 164 }
//