主页面:http://www.cnblogs.com/DOLFAMINGO/p/7538588.html
(代码一直在精简完善……)
代码一:两个BFS, 两段代码; 用step控制“你一步, 我一步”。


1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cmath> 5 #include <algorithm> 6 #include <vector> 7 #include <queue> 8 #include <stack> 9 #include <map> 10 #include <string> 11 #include <set> 12 #define ms(a,b) memset((a),(b),sizeof((a))) 13 using namespace std; 14 typedef long long LL; 15 const int INF = 2e9; 16 const LL LNF = 9e18; 17 const int MOD = 1e9+7; 18 const int MAXN = 1e6+10; 19 20 struct node 21 { 22 int status; 23 int s[9]; 24 int loc; 25 int step; //双向bfs需要记录第几步,才能做到“你一步,我一步” 26 }; 27 28 int fac[9] = { 1, 1, 2, 6, 24, 120, 720, 5040, 40320}; 29 int dir1[4][2] = { -1,0, 1,0, 0,-1, 0,1 }; //正方向 30 char op1[4] = {'u', 'd', 'l', 'r' }; 31 int dir2[4][2] = {0,1, 0,-1, 1,0, -1,0}; //反方向 32 char op2[4] = {'l', 'r', 'u', 'd' }; 33 34 char path1[MAXN], path2[MAXN]; //1为正方向,2为反方向,以下皆如此 35 int pre1[MAXN], pre2[MAXN]; 36 37 int cantor(int s[]) 38 { 39 int sum = 0; 40 for(int i = 0; i<9; i++) 41 { 42 int num = 0; 43 for(int j = i+1; j<9; j++) 44 if(s[j]<s[i]) 45 num++; 46 sum += num*fac[8-i]; 47 } 48 return sum+1; 49 } 50 51 queue<node>q1, q2; 52 int vis1[MAXN], vis2[MAXN]; 53 int bfs(node now) 54 { 55 ms(vis1,0); 56 ms(vis2,0); 57 while(!q1.empty()) q1.pop(); 58 while(!q2.empty()) q2.pop(); 59 60 now.status = cantor(now.s); 61 now.step = 0; 62 pre1[now.status] = -1; 63 vis1[now.status] = 1; 64 q1.push(now); 65 66 for(int i = 0; i<9; i++) 67 now.s[i] = i+1; 68 now.loc = 8; 69 now.status = cantor(now.s); 70 now.step = 0; 71 pre2[now.status] = -1; 72 vis2[now.status] = 1; 73 q2.push(now); 74 75 int time = 0; //计时器 76 while(!q1.empty() || !q2.empty()) 77 { 78 time++; 79 while(!q1.empty()) 80 { 81 if(q1.front().step==time) //时间到了,就让给对方 82 break; 83 84 now = q1.front(); 85 q1.pop(); 86 87 if(vis2[now.status]) //此状态已被对方访问过,则说明两者“接上了” 88 return now.status; 89 90 int x = now.loc/3; 91 int y = now.loc%3; 92 for(int i = 0; i<4; i++) 93 { 94 int xx = x + dir1[i][0]; 95 int yy = y + dir1[i][1]; 96 if(xx>=0 && xx<=2 && yy>=0 && yy<=2) 97 { 98 node tmp = now; 99 tmp.s[x*3+y] = tmp.s[xx*3+yy]; 100 tmp.s[xx*3+yy] = 9; 101 tmp.status = cantor(tmp.s); 102 if(!vis1[tmp.status]) 103 { 104 vis1[tmp.status] = 1; 105 tmp.loc = xx*3+yy; 106 tmp.step++; 107 path1[tmp.status] = op1[i]; 108 pre1[tmp.status] = now.status; 109 q1.push(tmp); 110 } 111 } 112 } 113 } 114 115 while(!q2.empty()) 116 { 117 if(q2.front().step==time) //时间到了,就让给对方 118 break; 119 120 now = q2.front(); 121 q2.pop(); 122 123 if(vis1[now.status]) //此状态已被对方访问过,则说明两者“接上了” 124 return now.status; 125 126 int x = now.loc/3; 127 int y = now.loc%3; 128 for(int i = 0; i<4; i++) 129 { 130 int xx = x + dir2[i][0]; 131 int yy = y + dir2[i][1]; 132 if(xx>=0 && xx<=2 && yy>=0 && yy<=2) 133 { 134 node tmp = now; 135 tmp.s[x*3+y] = tmp.s[xx*3+yy]; 136 tmp.s[xx*3+yy] = 9; 137 tmp.status = cantor(tmp.s); 138 if(!vis2[tmp.status]) 139 { 140 vis2[tmp.status] = 1; 141 tmp.loc = xx*3+yy; 142 tmp.step++; 143 path2[tmp.status] = op2[i]; 144 pre2[tmp.status] = now.status; 145 q2.push(tmp); 146 } 147 } 148 } 149 } 150 } 151 return -1; 152 } 153 154 155 void Print1(int status) //输出正方向的路径 156 { 157 if(pre1[status]==-1) return; 158 Print1(pre1[status]); 159 putchar(path1[status]); 160 } 161 162 void Print2(int status) //输出反方向的路径 163 { 164 if(pre2[status]==-1) return; 165 putchar(path2[status]); 166 Print2(pre2[status]); 167 } 168 169 int main() 170 { 171 char tmp[50]; 172 while(gets(tmp)) 173 { 174 node beg; 175 int cnt = 0; 176 for(int i = 0; tmp[i]; i++) 177 { 178 if(tmp[i]==' ') continue; 179 if(tmp[i]=='x') beg.s[cnt] = 9, beg.loc = cnt++; 180 else beg.s[cnt++] = tmp[i]-'0'; 181 } 182 int status = bfs(beg); 183 if(status==-1) 184 puts("unsolvable"); 185 else 186 { 187 Print1(status); Print2(status); //输出路径 188 putchar('\n'); 189 } 190 } 191 }
代码二:两个BFS, 两段代码; 用队列的大小控制“你一步, 我一步”。


1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cmath> 5 #include <algorithm> 6 #include <vector> 7 #include <queue> 8 #include <stack> 9 #include <map> 10 #include <string> 11 #include <set> 12 #define ms(a,b) memset((a),(b),sizeof((a))) 13 using namespace std; 14 typedef long long LL; 15 const int INF = 2e9; 16 const LL LNF = 9e18; 17 const int MOD = 1e9+7; 18 const int MAXN = 1e6+10; 19 20 struct node 21 { 22 int status; 23 int s[9]; 24 int loc; 25 }; 26 27 int fac[9] = { 1, 1, 2, 6, 24, 120, 720, 5040, 40320}; 28 int dir1[4][2] = { -1,0, 1,0, 0,-1, 0,1 }; //正方向 29 char op1[4] = {'u', 'd', 'l', 'r' }; 30 int dir2[4][2] = {0,1, 0,-1, 1,0, -1,0}; //反方向 31 char op2[4] = {'l', 'r', 'u', 'd' }; 32 33 char path1[MAXN], path2[MAXN]; //1为正方向,2为反方向,以下皆如此 34 int pre1[MAXN], pre2[MAXN]; 35 36 int cantor(int s[]) 37 { 38 int sum = 0; 39 for(int i = 0; i<9; i++) 40 { 41 int num = 0; 42 for(int j = i+1; j<9; j++) 43 if(s[j]<s[i]) 44 num++; 45 sum += num*fac[8-i]; 46 } 47 return sum+1; 48 } 49 50 queue<node>q1, q2; 51 int vis1[MAXN], vis2[MAXN]; 52 int bfs(node now) 53 { 54 ms(vis1,0); 55 ms(vis2,0); 56 while(!q1.empty()) q1.pop(); 57 while(!q2.empty()) q2.pop(); 58 59 now.status = cantor(now.s); 60 pre1[now.status] = -1; 61 vis1[now.status] = 1; 62 q1.push(now); 63 64 for(int i = 0; i<9; i++) 65 now.s[i] = i+1; 66 now.loc = 8; 67 now.status = cantor(now.s); 68 pre2[now.status] = -1; 69 vis2[now.status] = 1; 70 q2.push(now); 71 72 while(!q1.empty() || !q2.empty()) 73 { 74 int s1 = q1.size(); //当前队列中的结点步数是一样的,处理完这些结点,得到步数+1的结点 75 while(s1--) 76 { 77 now = q1.front(); 78 q1.pop(); 79 80 if(vis2[now.status]) //此状态已被对方访问过,则说明两者“接上了” 81 return now.status; 82 83 int x = now.loc/3; 84 int y = now.loc%3; 85 for(int i = 0; i<4; i++) 86 { 87 int xx = x + dir1[i][0]; 88 int yy = y + dir1[i][1]; 89 if(xx>=0 && xx<=2 && yy>=0 && yy<=2) 90 { 91 node tmp = now; 92 tmp.s[x*3+y] = tmp.s[xx*3+yy]; 93 tmp.s[xx*3+yy] = 9; 94 tmp.status = cantor(tmp.s); 95 if(!vis1[tmp.status]) 96 { 97 vis1[tmp.status] = 1; 98 tmp.loc = xx*3+yy; 99 path1[tmp.status] = op1[i]; 100 pre1[tmp.status] = now.status; 101 q1.push(tmp); 102 } 103 } 104 } 105 } 106 107 int s2 = q2.size(); 108 while(s2--) 109 { 110 now = q2.front(); 111 q2.pop(); 112 113 if(vis1[now.status]) //此状态已被对方访问过,则说明两者“接上了” 114 return now.status; 115 116 int x = now.loc/3; 117 int y = now.loc%3; 118 for(int i = 0; i<4; i++) 119 { 120 int xx = x + dir2[i][0]; 121 int yy = y + dir2[i][1]; 122 if(xx>=0 && xx<=2 && yy>=0 && yy<=2) 123 { 124 node tmp = now; 125 tmp.s[x*3+y] = tmp.s[xx*3+yy]; 126 tmp.s[xx*3+yy] = 9; 127 tmp.status = cantor(tmp.s); 128 if(!vis2[tmp.status]) 129 { 130 vis2[tmp.status] = 1; 131 tmp.loc = xx*3+yy; 132 path2[tmp.status] = op2[i]; 133 pre2[tmp.status] = now.status; 134 q2.push(tmp); 135 } 136 } 137 } 138 } 139 } 140 return -1; 141 } 142 143 void Print1(int status) //输出正方向的路径 144 { 145 if(pre1[status]==-1) return; 146 Print1(pre1[status]); 147 putchar(path1[status]); 148 } 149 150 void Print2(int status) //输出反方向的路径 151 { 152 if(pre2[status]==-1) return; 153 putchar(path2[status]); 154 Print2(pre2[status]); 155 } 156 157 int main() 158 { 159 char tmp[50]; 160 while(gets(tmp)) 161 { 162 node beg; 163 int cnt = 0; 164 for(int i = 0; tmp[i]; i++) 165 { 166 if(tmp[i]==' ') continue; 167 if(tmp[i]=='x') beg.s[cnt] = 9, beg.loc = cnt++; 168 else beg.s[cnt++] = tmp[i]-'0'; 169 } 170 int status = bfs(beg); 171 if(status==-1) 172 puts("unsolvable"); 173 else 174 { 175 Print1(status); Print2(status); //输出路径 176 putchar('\n'); 177 } 178 } 179 }
代码三:两个队列,调用一段BFS(),用队列的大小控制“你一步, 我一步”。


1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cmath> 5 #include <algorithm> 6 #include <vector> 7 #include <queue> 8 #include <stack> 9 #include <map> 10 #include <string> 11 #include <set> 12 #define ms(a,b) memset((a),(b),sizeof((a))) 13 using namespace std; 14 typedef long long LL; 15 const int INF = 2e9; 16 const LL LNF = 9e18; 17 const int MOD = 1e9+7; 18 const int MAXN = 1e6+10; 19 20 struct node 21 { 22 int status; 23 int s[9]; 24 int loc; 25 }; 26 27 int fac[9] = { 1, 1, 2, 6, 24, 120, 720, 5040, 40320}; 28 int dir[2][4][2] = { -1,0, 1,0, 0,-1, 0,1, 0,1, 0,-1, 1,0, -1,0}; //正方向 29 char op[2][4] = {'u', 'd', 'l', 'r' , 'l', 'r', 'u', 'd' }; 30 31 char path[2][MAXN]; 32 int pre[2][MAXN]; 33 34 int cantor(int s[]) 35 { 36 int sum = 0; 37 for(int i = 0; i<9; i++) 38 { 39 int num = 0; 40 for(int j = i+1; j<9; j++) 41 if(s[j]<s[i]) 42 num++; 43 sum += num*fac[8-i]; 44 } 45 return sum+1; 46 } 47 48 queue<node>q[2]; 49 int vis[2][MAXN]; 50 int bfs(int id) 51 { 52 int Size = q[id].size(); 53 while(Size--) 54 { 55 node now = q[id].front(); 56 q[id].pop(); 57 58 if(vis[!id][now.status]) 59 return now.status; 60 61 int x = now.loc/3; 62 int y = now.loc%3; 63 for(int i = 0; i<4; i++) 64 { 65 int xx = x + dir[id][i][0]; 66 int yy = y + dir[id][i][1]; 67 if(xx>=0 && xx<=2 && yy>=0 && yy<=2) 68 { 69 node tmp = now; 70 tmp.s[x*3+y] = tmp.s[xx*3+yy]; 71 tmp.s[xx*3+yy] = 9; 72 tmp.status = cantor(tmp.s); 73 if(!vis[id][tmp.status]) 74 { 75 vis[id][tmp.status] = 1; 76 tmp.loc = xx*3+yy; 77 path[id][tmp.status] = op[id][i]; 78 pre[id][tmp.status] = now.status; 79 q[id].push(tmp); 80 } 81 } 82 } 83 } 84 return -1; 85 } 86 87 int solve(node now) //把两个bfs缩在一起写, 精简代码 88 { 89 ms(vis,0); 90 while(!q[0].empty()) q[0].pop(); 91 while(!q[1].empty()) q[1].pop(); 92 93 now.status = cantor(now.s); 94 pre[0][now.status] = -1; 95 vis[0][now.status] = 1; 96 q[0].push(now); 97 98 for(int i = 0; i<9; i++) 99 now.s[i] = i+1; 100 now.loc = 8; 101 now.status = cantor(now.s); 102 pre[1][now.status] = -1; 103 vis[1][now.status] = 1; 104 q[1].push(now); 105 106 int time = 0, ret; 107 while(!q[0].empty() ||!q[1].empty()) 108 { 109 ret = bfs(0); 110 if(ret!=-1) return ret; 111 ret = bfs(1); 112 if(ret!=-1) return ret; 113 time++; 114 } 115 return -1; 116 } 117 118 void Print1(int status) //输出正方向的路径 119 { 120 if(pre[0][status]==-1) return; 121 Print1(pre[0][status]); 122 putchar(path[0][status]); 123 } 124 125 void Print2(int status) //输出反方向的路径 126 { 127 if(pre[1][status]==-1) return; 128 putchar(path[1][status]); 129 Print2(pre[1][status]); 130 } 131 132 int main() 133 { 134 char tmp[50]; 135 while(gets(tmp)) 136 { 137 node beg; 138 int cnt = 0; 139 for(int i = 0; tmp[i]; i++) 140 { 141 if(tmp[i]==' ') continue; 142 if(tmp[i]=='x') beg.s[cnt] = 9, beg.loc = cnt++; 143 else beg.s[cnt++] = tmp[i]-'0'; 144 } 145 int status = solve(beg); 146 if(status==-1) 147 puts("unsolvable"); 148 else 149 { 150 Print1(status); Print2(status); //输出路径 151 putchar('\n'); 152 } 153 } 154 }
代码四:一个队列(将正反两方向的结点都丢进同一个队列, 保证了“你一步我一步”), 一段BFS。


1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cmath> 5 #include <algorithm> 6 #include <vector> 7 #include <queue> 8 #include <stack> 9 #include <map> 10 #include <string> 11 #include <set> 12 #define ms(a,b) memset((a),(b),sizeof((a))) 13 using namespace std; 14 typedef long long LL; 15 const int INF = 2e9; 16 const LL LNF = 9e18; 17 const int MOD = 1e9+7; 18 const int MAXN = 1e6+10; 19 20 struct node 21 { 22 int status; 23 int s[9]; 24 int loc; 25 int id; //id标记正反方向 26 }; 27 28 int fac[9] = { 1, 1, 2, 6, 24, 120, 720, 5040, 40320}; 29 int dir[2][4][2] = { -1,0, 1,0, 0,-1, 0,1, 0,1, 0,-1, 1,0, -1,0}; //正方向 30 char op[2][4] = {'u', 'd', 'l', 'r' , 'l', 'r', 'u', 'd' }; 31 32 char path[2][MAXN]; 33 int pre[2][MAXN]; 34 35 int cantor(int s[]) 36 { 37 int sum = 0; 38 for(int i = 0; i<9; i++) 39 { 40 int num = 0; 41 for(int j = i+1; j<9; j++) 42 if(s[j]<s[i]) 43 num++; 44 sum += num*fac[8-i]; 45 } 46 return sum+1; 47 } 48 49 queue<node>que; 50 int vis[2][MAXN]; 51 int bfs(node now) //把两个bfs缩在一起写, 精简代码 52 { 53 ms(vis,0); 54 while(!que.empty()) que.pop(); 55 56 now.status = cantor(now.s); 57 now.id = 0; 58 pre[0][now.status] = -1; 59 vis[0][now.status] = 1; 60 que.push(now); 61 62 for(int i = 0; i<9; i++) 63 now.s[i] = i+1; 64 now.loc = 8; 65 now.status = cantor(now.s); 66 now.id = 1; 67 pre[1][now.status] = -1; 68 vis[1][now.status] = 1; 69 que.push(now); 70 71 while(!que.empty()) 72 { 73 node now = que.front(); 74 que.pop(); 75 76 if(vis[!now.id][now.status]) 77 return now.status; 78 79 int x = now.loc/3; 80 int y = now.loc%3; 81 for(int i = 0; i<4; i++) 82 { 83 int xx = x + dir[now.id][i][0]; 84 int yy = y + dir[now.id][i][1]; 85 if(xx>=0 && xx<=2 && yy>=0 && yy<=2) 86 { 87 node tmp = now; 88 tmp.s[x*3+y] = tmp.s[xx*3+yy]; 89 tmp.s[xx*3+yy] = 9; 90 tmp.status = cantor(tmp.s); 91 if(!vis[now.id][tmp.status]) 92 { 93 vis[now.id][tmp.status] = 1; 94 tmp.loc = xx*3+yy; 95 path[now.id][tmp.status] = op[now.id][i]; 96 pre[now.id][tmp.status] = now.status; 97 que.push(tmp); 98 } 99 } 100 } 101 } 102 } 103 104 void Print1(int status) //输出正方向的路径 105 { 106 if(pre[0][status]==-1) return; 107 Print1(pre[0][status]); 108 putchar(path[0][status]); 109 } 110 111 void Print2(int status) //输出反方向的路径 112 { 113 if(pre[1][status]==-1) return; 114 putchar(path[1][status]); 115 Print2(pre[1][status]); 116 } 117 118 int main() 119 { 120 char tmp[50]; 121 while(gets(tmp)) 122 { 123 node beg; 124 int cnt = 0; 125 for(int i = 0; tmp[i]; i++) 126 { 127 if(tmp[i]==' ') continue; 128 if(tmp[i]=='x') beg.s[cnt] = 9, beg.loc = cnt++; 129 else beg.s[cnt++] = tmp[i]-'0'; 130 } 131 int status = bfs(beg); 132 if(status==-1) 133 puts("unsolvable"); 134 else 135 { 136 Print1(status); Print2(status); //输出路径 137 putchar('\n'); 138 } 139 } 140 }