POJ1077 Eight —— 双向BFS

主页面: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 }
View Code


代码二:两个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 }
View Code

 



代码三:两个队列,调用一段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 }
View Code


代码四:一个队列(将正反两方向的结点都丢进同一个队列, 保证了“你一步我一步”), 一段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 }
View Code

 


 




 

转载于:https://www.cnblogs.com/DOLFAMINGO/p/7538585.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值