学习了多位大牛的方法,看看到底能把时耗降到多少?
A*
1 // zojfulltest: 30000ms 2 # include <stdio.h> 3 # include <ctype.h> 4 # include <stdlib.h> 5 # include <string.h> 6 7 # define DATA(x,i) (((x)>>((i)*3))&0x7) 8 # define ZERO(x) ((x)>>27) 9 # define F(x) ((x)&0xFF) 10 # define D(x) (((x)>>8)&0xF) 11 # define P(x) ((x)>>12) 12 # define MAKE(f,d,p) ((f)|((d)<<8)|((p)<<12)) 13 # define LESS(x,y) (((x)-(y))>>31) 14 # define SWP(i,j,t) (((t)<<(3*(i)))-((t)<<(3*(j)))+((j)<<27)-((i)<<27)) 15 16 const unsigned int maxd = 35; 17 //dest: 0100 0000 0001 1111 0101 1000 1101 0001 18 const unsigned int dest = 0x401F58D1; 19 const unsigned int hashmod = 10007; 20 const unsigned int maxnode = 0x1<<15; 21 const unsigned int maxsize = 0x1<<13; 22 const int mv[][4] = {{-1,-1,1, 3},{-1,0,2, 4},{-1,1,-1, 5}, 23 { 0,-1,4, 6},{ 1,3,5, 7},{ 2,4,-1, 8}, 24 { 3,-1,7,-1},{ 4,6,8,-1},{ 5,7,-1,-1}}; 25 const char mvs[] = "ulrd"; 26 27 struct state { 28 unsigned int u, v; 29 }; 30 state a[maxnode], child; 31 unsigned int src, depth, totnode, h[9][9], t[9]; 32 unsigned int head[hashmod], next[maxnode]; 33 unsigned int hp[maxsize], hps; 34 unsigned int stk[maxsize], top; 35 36 void init(void) 37 { 38 memset(h, 0, sizeof(h)); 39 for (int j, i = 1; i != 9; ++i) { 40 for (j = 0; j != 9; ++j) { 41 h[i][j] = abs(j/3-(i-1)/3)+abs(j%3-(i-1)%3); 42 } 43 } 44 for (int i = 0; i != 9; ++i) { 45 h[0][i] = h[8][i]; 46 } 47 } 48 bool read_src(void) 49 { 50 src = 0; 51 for (int ch, i = 0; i != 9; ) { 52 ch = getchar(); 53 if (isdigit(ch)) t[i++] = ch-'0'; 54 else if (ch == 'x') { 55 t[i] = 0; 56 src |= ((i++)<<27); 57 } else if (ch == EOF) return false; 58 } 59 for (int i = 0; i != 9; ++i) src |= ((t[i]&0x7)<<(3*i)); 60 return true; 61 } 62 bool no_answer(void) 63 { 64 int inv = -ZERO(src), i, j; 65 for (i = 0; i != 8; ++i) { 66 for (j = i+1; j != 9; ++j) { 67 inv += LESS(t[j],t[i]); 68 } 69 } 70 return ((inv)&0x1); 71 } 72 void print_sol(int ID) 73 { 74 if (ID == 1) return ; 75 print_sol(P(a[ID].v)); 76 putchar( mvs[D(a[ID].v)] ); 77 } 78 void addnode(void) 79 { 80 int k = child.u % hashmod; 81 for (int w = head[k]; w ; w = next[w]) { 82 if (a[w].u == child.u) { 83 if ( LESS(F(child.v), F(a[w].v)) ) { 84 a[w].v = child.v; 85 stk[top++] = w; 86 } 87 return ; 88 } 89 } 90 a[++totnode] = child; 91 next[totnode] = head[k]; head[k] = totnode; 92 if ( F(child.v) == depth ) stk[top++] = totnode; 93 else hp[hps++] = totnode; 94 } 95 96 void solve(void) 97 { 98 if (no_answer()) { puts("unsolvable"); return; } 99 if (src == dest) { puts(""); return ; } 100 depth = -h[0][ZERO(src)]; 101 totnode = 0; 102 hps = top = 0; 103 memset(head, 0, sizeof(head)); 104 for (int i = 0; i != 9; ++i) { 105 depth += h[ DATA(src,i) ][i]; 106 } 107 child.u = src; 108 child.v = MAKE(depth, 4, 1); 109 addnode(); 110 unsigned int ID; 111 for ( ; LESS(depth, maxd); depth += 2) { 112 while (hps) { 113 ID = hp[--hps]; 114 if ( F(a[ID].v) == depth ) { 115 stk[top++] = ID; 116 } 117 } 118 while (top) { 119 ID = stk[--top]; 120 state & cur = a[ID]; 121 int i = ZERO(cur.u), j; 122 for (int r = 0; r != 4; ++r) { 123 if (-1!=(j=mv[i][r]) && (D(cur.v)+r)!=3) { 124 int t = DATA(cur.u, j); 125 child.u = cur.u+SWP(i,j,t); 126 int f = F(cur.v)+1+h[t][i]-h[t][j]; 127 child.v = MAKE(f,r,ID); 128 if (child.u == dest) { 129 a[++totnode] = child; 130 print_sol(totnode); puts(""); 131 return ; 132 } 133 addnode(); 134 } 135 } 136 } 137 } 138 } 139 140 int main() 141 { 142 init(); 143 while (read_src()) solve(); 144 145 return 0; 146 }