• 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('
    ');
    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('
    ');
    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('
    ');
    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('
    ');
    138         }
    139     }
    140 }
    View Code





  • 相关阅读:
    sqlserver中临时表、row-number、update更新自己
    easyui 实现Tooltip
    easyui 添加dialog
    转载 50种方法优化SQL Server数据库查询
    用正则将空格给去掉
    java连接redis无法连接,报异常RedisConnectionException
    springcloud的Turbine配置监控多个服务的一些坑!!!!InstanceMonitor$MisconfiguredHostException,No message available","path":"/actuator/hystrix.stream,页面不显示服务或者一直loading
    CentOS7最小化安装之后无法联网以及无法使用ifconfig以及无法使用yum安装软件
    required_new spring事务传播行为无效碰到的坑!
    推荐一下牛逼的谷歌浏览器插件!!!非常好用
  • 原文地址:https://www.cnblogs.com/DOLFAMINGO/p/7538585.html
Copyright © 2020-2023  润新知