poj 1077 八数码
1 #include<iostream> 2 #include<queue> 3 #include<algorithm> 4 #include<string> 5 #include<cstring> 6 #include<cstdio> 7 //正向广度搜索 8 //把“x"当初0 9 using namespace std; 10 11 const int maxn = 1000000; 12 13 int fac[] = { 1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880 }; //康拖展开判重 14 // 0! 1! 2! 3! 4! 5! 6! 7! 8! 9! 15 int vis[maxn]; 16 17 int get_priority(int s[]){ //康拖展开求该序列的hash值 18 int sum = 0; 19 for (int i = 0; i<9; i++){ 20 int cnt = 0; 21 for (int j = i + 1; j<9; j++) 22 if (s[i]>s[j]) 23 cnt++; 24 sum += (cnt*fac[9 - i - 1]); 25 } 26 return sum + 1; 27 } 28 29 struct node{ 30 int s[9]; 31 int loc; //“0”的位置,把“x"当0 32 int status; //康拖展开的hash值 33 string path; //路径 34 }start; 35 36 string path; 37 int aim = 46234; //123456780对应的康拖展开的hash值 38 int dir[4][2] = { { -1, 0 }, { 1, 0 }, { 0, -1 }, { 0, 1 } };//u,d,l,r 39 char indexs[5] = "udlr";//正向搜索 40 41 int BFS(){ 42 queue<node> q; 43 while (!q.empty()) 44 q.pop(); 45 node cur, next; 46 q.push(start); 47 int x, y; 48 while (!q.empty()){ 49 cur = q.front(); 50 q.pop(); 51 if (cur.status == aim){ 52 path = cur.path; 53 return 1; 54 } 55 x = cur.loc / 3; 56 y = cur.loc % 3; 57 for (int i = 0; i<4; i++){ 58 int tx = x + dir[i][0]; 59 int ty = y + dir[i][1]; 60 if (tx<0 || tx >= 3 || ty<0 || ty >= 3) 61 continue; 62 next = cur; 63 next.loc = tx * 3 + ty; 64 next.s[cur.loc] = next.s[next.loc]; 65 next.s[next.loc] = 0; 66 next.status = get_priority(next.s); 67 if (!vis[next.status]){ 68 vis[next.status] = 1; 69 next.path = next.path + indexs[i]; 70 if (next.status == aim){ 71 path = next.path; 72 return 1; 73 } 74 q.push(next); 75 } 76 } 77 } 78 return 0; 79 } 80 81 int main(){ 82 83 //freopen("input.txt","r",stdin); 84 85 char ch; 86 while (cin >> ch){ 87 if (ch == 'x'){ 88 start.s[0] = 0; 89 start.loc = 0; 90 } 91 else 92 start.s[0] = ch - '0'; 93 for (int i = 1; i<9; i++){ 94 cin >> ch; 95 if (ch == 'x'){ 96 start.s[i] = 0; 97 start.loc = i; 98 } 99 else 100 start.s[i] = ch - '0'; 101 } 102 start.status = get_priority(start.s); 103 memset(vis, 0, sizeof(vis)); 104 if (BFS()) 105 cout << path << endl; 106 else 107 printf("unsolvable\n"); 108 } 109 return 0; 110 }
1 void GetNode(int num, int *str) { 2 int n = 9; 3 int a[9]; 4 for (int i = 2; i <= n; ++i) 5 { 6 a[i - 1] = num%i; 7 num = num / i; 8 str[i - 1] = 0; 9 } 10 str[0] = 0; 11 int rn, i; 12 for (int k = n; k >= 2; k--) 13 { 14 rn = 0; 15 for (i = n - 1; i >= 0; --i) 16 { 17 if (str[i] != 0) 18 continue; 19 if (rn == a[k - 1]) 20 break; 21 ++rn; 22 } 23 str[i] = k; 24 } 25 for (i = 0; i<n; ++i) 26 if (str[i] == 0) 27 { 28 str[i] = 1; 29 break; 30 } 31 }
1 //没看懂神牛路径怎么打印的。。QAQ 2 # include <stdio.h> 3 # include <string.h> 4 5 # define N 9 6 # define MAXN (362880 + 10) 7 8 typedef struct{ int k; char d; }foot; 9 typedef struct{ char a[N]; }state; 10 11 const char md[4] = {'u', 'l', 'r', 'd'}; 12 const char d[4][2] = {{-1,0}, {0,-1}, {0,1}, {1,0}}; 13 const int fact[9] = {1, 1, 2, 6, 24, 120, 720, 720*7, 720*56}; 14 15 state Q[MAXN/10]; 16 char vis[MAXN]; 17 foot p[MAXN]; 18 19 int cantor(state s) 20 { 21 char ch; 22 int i, j, cnt, ret; 23 24 ret = 0; 25 for (i = 0; i < N-1; ++i) 26 { 27 cnt = 0; 28 ch = s.a[i]; 29 for (j = i+1; j < N; ++j) 30 if (s.a[j] < ch) ++cnt; 31 ret += cnt*fact[8-i]; 32 } 33 34 return ret; 35 } 36 37 char bool_inv(state s) 38 { 39 char ch, ret; 40 int i, j; 41 42 ret = 0; 43 for (i = 0; i < N-1; ++i) 44 { 45 if ((ch = s.a[i]) == 0) continue; 46 for (j = i+1; j < N; ++j) 47 if (s.a[j] && s.a[j] < ch) ret = 1 - ret; 48 } 49 50 return ret; 51 } 52 53 void print_path(int x, char f) 54 { 55 if (p[x].k == 0) return ; 56 if (f) putchar(md[3-p[x].d]); 57 print_path(p[x].k, f); 58 if (!f) putchar(md[p[x].d]); 59 } 60 61 void bfs(state start, state goal) 62 { 63 char t; 64 state cur, nst; 65 int front, rear, i; 66 int x, y, nx, ny, ct, nt; 67 68 Q[front = 1] = start; 69 Q[rear = 2] = goal; 70 vis[cantor(start)] = 1; 71 vis[cantor(goal)] = 2; 72 73 while (front <= rear) 74 { 75 cur = Q[front++]; 76 ct = cantor(cur); 77 for (i = 0; cur.a[i] && i < N; ++i) ; 78 x = i / 3; y = i % 3; 79 for (i = 0; i < 4; ++i) 80 { 81 nx = x + d[i][0]; ny = y + d[i][1]; 82 if (nx>=0 && nx<3 && ny>=0 && ny<3) 83 { 84 nst = cur; 85 nst.a[x*3+y] = cur.a[nx*3+ny]; 86 nst.a[nx*3+ny] = 0; 87 nt = cantor(nst); 88 if (!vis[nt]) 89 { 90 Q[++rear] = nst; 91 p[nt].k = ct; 92 p[nt].d = i; 93 vis[nt] = vis[ct]; 94 } 95 else if (vis[ct] != vis[nt]) 96 { 97 t = (vis[ct]==1 ? 1:0); 98 print_path(t ? ct:nt, 0); 99 putchar(md[t ? i:3-i]); 100 print_path(t ? nt:ct, 1); 101 putchar('\n'); 102 return ; 103 } 104 } 105 } 106 } 107 } 108 109 int main() 110 { 111 char i, c[5]; 112 state start, goal; 113 114 for (i = 0; i < N; ++i) 115 { 116 scanf("%s", c); 117 start.a[i] = (c[0]=='x' ? 0:c[0]-'0'); 118 } 119 goal.a[8] = 0; 120 for (i = 0; i < N-1; ++i) 121 goal.a[i] = i + 1; 122 123 for (i = 0; start.a[i] == goal.a[i] && i < N; ++i) ; 124 if (i == N) puts(""); 125 else if (bool_inv(start) != bool_inv(goal)) puts("unsolvable"); 126 else bfs(start, goal); 127 128 return 0; 129 }