eight - zoj 1217 poj 1077
学习了多位大牛的方法,看看到底能把时耗降到多少?
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 }
BFS + 记忆化
1 // zojfulltest: 1012ms 2 # include <stdio.h> 3 # include <ctype.h> 4 # include <string.h> 5 6 # define LESS(x,y) (((x)-(y))>>31) 7 # define DATA(x,i) (((x)>>((i)*3))&0x7) 8 # define ZERO(x) ((x)>>27) 9 # define P(x) ((x)>>4) 10 # define D(x) ((x)&0xF) 11 # define MAKE(d,p) ((d)|((p)<<4)) 12 # define SWP(i,j,t) (((t)<<(3*(i)))-((t)<<(3*(j)))+((j)<<27)-((i)<<27)) 13 14 const int totnode = 362881; 15 const int maxsize = 181445; 16 const int dest = 0x401F58D1; 17 const int destID = 40319; 18 const int fact[] = {1,1,2,6,24,120,720,5040,40320}; 19 const int mv[][4] = {{-1,-1,1, 3},{-1,0,2, 4},{-1,1,-1, 5}, 20 { 0,-1,4, 6},{ 1,3,5, 7},{ 2,4,-1, 8}, 21 { 3,-1,7,-1},{ 4,6,8,-1},{ 5,7,-1,-1}}; 22 const char mvs[] = "ulrd"; 23 24 struct state { 25 unsigned int s; 26 unsigned int c; 27 } hp[maxsize], child; 28 29 unsigned int front, rear, src, table[totnode]; 30 31 unsigned int cantor(unsigned int s) 32 { 33 unsigned int ret = 0; 34 unsigned int t[9], i; 35 for (i = 0; i != 9; ++i) t[i] = DATA(s,i); 36 for (i = 0; DATA(s,i)||i==ZERO(s); ++i) ; 37 t[i] = 8; 38 for (i = 1; i != 9; ++i) { 39 unsigned int inv = 0; 40 for (int j = 0; j != i; ++j) { 41 inv += LESS(t[j],t[i]); 42 } 43 ret += inv*fact[i]; 44 } 45 return ret; 46 } 47 void build_tree(void) 48 { 49 front = rear = 0; 50 child.s = dest, child.c = destID; 51 table[destID] = MAKE(4,destID); 52 hp[rear++] = child; 53 while (LESS(front, rear)) { 54 state & cur = hp[front++]; 55 int i = ZERO(cur.s), d = table[cur.c], j; 56 for (int r = 0; r != 4; ++r) { 57 if (~(j=mv[i][r]) && (d+r)!=3) { 58 child.s = cur.s+SWP(i,j,DATA(cur.s,j)); 59 child.c = cantor(child.s); 60 if (table[child.c] == 0) { 61 table[child.c] = MAKE(r, cur.c); 62 hp[rear++] = child; 63 } 64 } 65 } 66 } 67 } 68 bool read_src(void) 69 { 70 src = 0; 71 for (int ch, i = 0; i != 9; ) { 72 ch = getchar(); 73 if (isdigit(ch)) src |= (((ch-'0')&0x7)<<(3*i++)); 74 else if (ch == 'x') src |= ((i++)<<27); 75 else if (ch == EOF) return false; 76 } 77 return true; 78 } 79 void print_sol(int ID) 80 { 81 while (ID != destID) { 82 putchar(mvs[3-D(table[ID])]); 83 ID = P(table[ID]); 84 } 85 } 86 void solve(void) 87 { 88 unsigned int c = cantor(src); 89 if (!table[c]) printf("unsolvable"); 90 else print_sol(c); 91 printf("\n"); 92 } 93 int main() 94 { 95 build_tree(); 96 while (read_src()) solve(); 97 }
构造
1 # include <stdio.h> 2 # include <ctype.h> 3 # include <string.h> 4 5 # define LESS(x, y) (((x)-(y))>>31) 6 # define REP(n) for ((i) = 0; src[i] != (n); ++(i)) 7 8 const char *t0[] = {"rd","d","ld","r","","l","ur","u","ul"}; 9 const char *t1[] = {"","lurd","urdllurd","uldr","","urdlurdllurd","ldruuldr","ldruldruuldr","rdluurdlurdllurd"}; 10 const char *t2[] = {"","urddllur","urdlurddllur","","","rdllur","ldru","dlur","druldlur"}; 11 const char *t3[] = {"","ruld","","","","urdl","dlurdrulurdlldru","drulurdl","rdluurdl"}; 12 const char *t4 = "ldrrulurdl"; 13 const char *t5[] = {"","","","","","rdllur","ldru","dlur","druldlur"}; 14 const char *t6[] = {"","","","","","rdlu","dlurdrulldrurdlu","","rdlurdlu"}; 15 const char *t7 = "dlur"; 16 const char *t8[] = {"","","","","","rd","","dr","rdlurd"}; 17 const char *mvs = "ulrd"; 18 const int mv[][4] = {{-1,-1,1, 3},{-1,0,2, 4},{-1,1,-1, 5}, 19 { 0,-1,4, 6},{ 1,3,5, 7},{ 2,4,-1, 8}, 20 { 3,-1,7,-1},{ 4,6,8,-1},{ 5,7,-1,-1} 21 }; 22 23 unsigned int src[9], pos; 24 char ans[100], top; 25 26 int mr(char ch) 27 { 28 switch(ch) { 29 case 'u': 30 return 0; 31 case 'l': 32 return 1; 33 case 'r': 34 return 2; 35 case 'd': 36 return 3; 37 } 38 } 39 void mov(const char * str) 40 { 41 int n = strlen(str); 42 for (int i = 0; i < n; ++i) { 43 int t = mv[pos][mr(str[i])]; 44 src[pos] = src[t]; 45 src[pos = t] = 0; 46 } 47 memcpy(ans+top, str, n); 48 top += n; 49 } 50 void solve(void) 51 { 52 int i; 53 top = 0; 54 mov( t0[pos] ); // 0->4 55 REP(1); 56 mov( t1[i] ); // 1->0 57 REP(3); 58 mov( t2[i] ); // 3->3 59 REP(2); 60 mov( t3[i] ); // 2->2 61 mov( t4 ); // 2->1, 3->2 62 REP(7); 63 mov( t5[i] ); // 7->3 64 REP(4); 65 mov( t6[i] ); // 4->7 66 mov( t7 ); // 4->3, 7->7 67 REP(5); 68 mov( t8[i] ); // 5->4, 0->8 69 ans[top] = 0; 70 if ( src[7] == 8 ) puts(ans); 71 } 72 bool no_answer(void) 73 { 74 int inv = -pos; 75 for (int i = 0; i != 8; ++i) { 76 for (int j = i+1; j != 9; ++j) { 77 inv += LESS(src[j], src[i]); 78 } 79 } 80 return ((inv)&0x1); 81 } 82 bool read_src(void) 83 { 84 for (int i = 0; i != 9; ) { 85 int ch = getchar(); 86 if (isdigit(ch)) src[i++] = ch-'0'; 87 else if (ch == 'x') src[pos = i++] = 0; 88 else if (ch == EOF) return false; 89 } 90 return true; 91 } 92 int main() 93 { 94 while ( read_src() ) { 95 if ( no_answer() ) puts("unsolvable"); 96 else solve(); 97 } 98 return 0; 99 }