首页 > 代码库 > 【HDOJ】1043 Eight
【HDOJ】1043 Eight
这道题目最开始做的时候wa+TLE。后面知道需要状态压缩,最近A掉。并且练习一下各种搜索算法。
1. 逆向BFS+康拓展开。
1 #include <iostream> 2 #include <queue> 3 #include <cstring> 4 #include <string> 5 #include <cstdio> 6 using namespace std; 7 8 #define N 9 9 #define MAXNUM 362880 10 11 typedef struct { 12 char map[N]; 13 int xpos; 14 string path; 15 } node_st; 16 17 int fact[N] = {1,1,2,6,24,120,720,5040,40320}; 18 int direct[4][2] = {{-1,0},{1,0},{0,-1},{0,1}}; 19 char rmove[4] = {‘d‘,‘u‘,‘r‘,‘l‘}; 20 char visit[MAXNUM]; 21 string rpath[MAXNUM]; 22 23 int cantor(node_st node) { 24 int i, j, cnt, val = 0; 25 26 for (i=0; i<N; ++i) { 27 cnt = 0; 28 for (j=i+1; j<N; ++j) { 29 if (node.map[j] < node.map[i]) 30 ++cnt; 31 } 32 val += fact[N-1-i]*cnt; 33 } 34 35 return val; 36 } 37 38 void bfs() { 39 queue<node_st> que; 40 node_st node; 41 int i, x, y, t1, t2, can; 42 43 for (i=1; i<N; ++i) 44 node.map[i-1] = ‘0‘ + i; 45 node.map[N-1] = ‘x‘; 46 node.xpos = N-1; 47 memset(visit, 0, sizeof(visit)); 48 visit[0] = 1; 49 que.push(node); 50 51 while ( !que.empty() ) { 52 node = que.front(); 53 que.pop(); 54 t1 = node.xpos / 3; 55 t2 = node.xpos % 3; 56 for (i=0; i<4; ++i) { 57 x = t1 + direct[i][0]; 58 y = t2 + direct[i][1]; 59 if (x<0 || x>=3 || y<0 || y>=3) 60 continue; 61 node_st tmp(node); 62 tmp.xpos = x*3+y; 63 tmp.map[node.xpos] = node.map[tmp.xpos]; 64 tmp.map[tmp.xpos] = ‘x‘; 65 can = cantor(tmp); 66 if ( !visit[can] ) { 67 visit[can] = 1; 68 tmp.path += rmove[i]; 69 rpath[can] = tmp.path; 70 que.push(tmp); 71 } 72 } 73 } 74 } 75 76 int main() { 77 node_st node; 78 int i, can; 79 80 bfs(); 81 82 while (scanf("%c%*c", &node.map[0]) != EOF) { 83 for (i=1; i<N; ++i) 84 scanf("%c%*c", &node.map[i]); 85 can = cantor(node); 86 if ( visit[can] ) { 87 for (i=rpath[can].size()-1; i>=0; --i) 88 printf("%c", rpath[can][i]); 89 printf("\n"); 90 } else { 91 printf("unsolvable\n"); 92 } 93 } 94 95 return 0; 96 }
2. 双端BFS。注意逆序奇偶性相同才有解。
1 #include <iostream> 2 #include <queue> 3 #include <string> 4 #include <algorithm> 5 #include <cstring> 6 #include <cstdio> 7 using namespace std; 8 9 #define N 9 10 #define MAXNUM 362880 11 12 typedef struct { 13 char map[N]; 14 int xpos; 15 string path; 16 } node_st; 17 18 int fact[N]={1,1,2,6,24,120,720,5040,40320}; 19 int direct[4][2] = {{-1,0},{1,0},{0,-1},{0,1}}; 20 char move[4] = {‘u‘,‘d‘,‘l‘,‘r‘}; 21 char rmove[4] = {‘d‘,‘u‘,‘r‘,‘l‘}; 22 char visit[MAXNUM]; 23 bool flag; 24 string paths[MAXNUM], fpath; 25 queue<node_st> que, rque; 26 27 28 inline int cantor(node_st node) { 29 int i, j, cnt, val = 0; 30 31 for (i=0; i<N; ++i) { 32 cnt = 0; 33 for (j=i+1; j<N; ++j) 34 if (node.map[j] < node.map[i]) 35 ++cnt; 36 val += fact[N-1-i]*cnt; 37 } 38 39 return val; 40 } 41 42 inline bool invNum(node_st node) { 43 int i, j, cnt = 0; 44 45 for (i=0; i<N; ++i) { 46 if (node.map[i] == ‘x‘) 47 continue; 48 for (j=i-1; j>=0; --j) 49 if (node.map[j]!=‘x‘ && node.map[j]>node.map[i]) 50 ++cnt; 51 } 52 53 return cnt&1; 54 } 55 56 void bfs() { 57 int x, y, can; 58 node_st node = que.front(); 59 que.pop(); 60 61 for (int i=0; i<4; ++i) { 62 x = node.xpos/3 + direct[i][0]; 63 y = node.xpos%3 + direct[i][1]; 64 if (x<0 || x>=3 || y<0 || y>=3) 65 continue; 66 node_st p(node); 67 p.map[p.xpos] = node.map[x*3+y]; 68 p.xpos = x*3+y; 69 p.map[p.xpos] = ‘x‘; 70 can = cantor(p); 71 if (visit[can] == 1) 72 continue; 73 p.path += move[i]; 74 if (visit[can] == -1) { 75 flag = false; 76 reverse(paths[can].begin(), paths[can].end()); 77 fpath = p.path + paths[can]; 78 return ; 79 } 80 visit[can] = 1; 81 paths[can] = p.path; 82 que.push(p); 83 } 84 } 85 86 void rbfs() { 87 int x, y, can; 88 node_st node = rque.front(); 89 rque.pop(); 90 91 for (int i=0; i<4; ++i) { 92 x = node.xpos/3 + direct[i][0]; 93 y = node.xpos%3 + direct[i][1]; 94 if (x<0 || x>=3 || y<0 || y>=3) 95 continue; 96 node_st p(node); 97 p.map[p.xpos] = node.map[x*3+y]; 98 p.xpos = x*3+y; 99 p.map[p.xpos] = ‘x‘; 100 can = cantor(p); 101 if (visit[can] == -1) 102 continue; 103 p.path += rmove[i]; 104 if (visit[can] == 1) { 105 flag = false; 106 reverse(p.path.begin(), p.path.end()); 107 fpath = paths[can] + p.path; 108 } 109 visit[can] = -1; 110 paths[can] = p.path; 111 rque.push(p); 112 } 113 } 114 115 int main() { 116 node_st node, enode; 117 int i, n, can; 118 119 for (i=1; i<N; ++i) 120 enode.map[i-1] = i + ‘0‘; 121 enode.map[N-1] = ‘x‘; 122 enode.xpos = N-1; 123 124 while (scanf("%c%*c", &node.map[0]) != EOF) { 125 for (i=0; i<N; ++i) { 126 if (i) 127 scanf("%c%*c", &node.map[i]); 128 if (node.map[i] == ‘x‘) 129 node.xpos = i; 130 } 131 if ( invNum(node) ) { 132 printf("unsolvable\n"); 133 continue; 134 } 135 can = cantor(node); 136 if ( can == 0 ) { 137 printf("\n"); 138 continue; 139 } 140 while ( !que.empty() ) 141 que.pop(); 142 while ( !rque.empty() ) 143 rque.pop(); 144 memset(visit, 0, sizeof(visit)); 145 flag = true; 146 rque.push(enode); 147 visit[0] = -1; 148 que.push(node); 149 visit[can] = 1; 150 while (flag) { 151 n = que.size(); 152 while (flag && n--) 153 bfs(); 154 n = rque.size(); 155 while (flag && n--) 156 rbfs(); 157 } 158 cout <<fpath<<endl; 159 } 160 161 return 0; 162 }
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。