zoukankan      html  css  js  c++  java
  • 【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("
    ");
    90         } else {
    91             printf("unsolvable
    ");
    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
    ");
    133             continue;
    134         }
    135         can = cantor(node);
    136         if ( can == 0 ) {
    137             printf("
    ");
    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 }

    3. A-star h函数为曼哈顿距离,必须用内联才不会TLE。

      1 #include <iostream>
      2 #include <queue>
      3 #include <stack>
      4 #include <string>
      5 #include <algorithm>
      6 #include <cstring>
      7 #include <cstdio>
      8 using namespace std;
      9 
     10 #define N 9
     11 #define MAXN 362880
     12 //#define myabs(x) ((x)>0) ? (x):(-(x))
     13 
     14 typedef struct node_st {
     15     char map[N];
     16     int xpos;
     17     int s, p;
     18     friend bool operator < (node_st a, node_st b) {
     19         return a.p > b.p;
     20     }
     21 } node_st;
     22 
     23 char visit[MAXN];
     24 int fact[N] = {1,1,2,6,24,120,720,5040,40320};
     25 int direct[4][2] = {{-1,0},{1,0},{0,-1},{0,1}};
     26 char move[4] = {'u', 'd', 'l', 'r'};
     27 int pre[MAXN], bcan;
     28 char op[MAXN];
     29 node_st beg;
     30 
     31 inline int cantor(node_st node) {
     32     int i, j, cnt, val = 0;
     33 
     34     for (i=0; i<N; ++i) {
     35         cnt = 0;
     36         for (j=i+1; j<N; ++j)
     37             if (node.map[j] < node.map[i])
     38                 ++cnt;
     39         val += fact[N-1-i]*cnt;
     40     }
     41 
     42     return val;
     43 }
     44 
     45 inline myabs(int x) {
     46     return (x>0) ? x:-x;
     47 }
     48 
     49 inline int h(node_st node) {
     50     int tmp, val = 0;
     51 
     52     for (int i=0; i<N; ++i) {
     53         if (node.map[i] == 'x') continue;
     54         tmp = node.map[i] - '1';
     55         val += myabs(tmp/3-i/3) + myabs(tmp%3-i%3);
     56     }
     57 
     58     return val;
     59 }
     60 
     61 inline bool invNum(node_st node) {
     62     int i, j, cnt = 0;
     63 
     64     for (i=0; i<N; ++i) {
     65         if (node.map[i] == 'x') continue;
     66         for (j=i-1; j>=0; --j)
     67             if (node.map[j]!='x' && node.map[j]>node.map[i])
     68                 ++cnt;
     69     }
     70 
     71     return cnt&1;
     72 }
     73 
     74 void bfs() {
     75     priority_queue<node_st> que;
     76     node_st node;
     77     int i, t1, t2, x, y, can, pcan;
     78 
     79     que.push(beg);
     80     memset(visit, 0, sizeof(visit));
     81     visit[bcan] = 1;
     82 
     83     while ( !que.empty() ) {
     84         node = que.top();
     85         que.pop();
     86         t1 = node.xpos / 3;
     87         t2 = node.xpos % 3;
     88         pcan = cantor(node);
     89         for (i=0; i<4; ++i) {
     90             x = t1 + direct[i][0];
     91             y = t2 + direct[i][1];
     92             if (x<0 || x>=3 || y<0 || y>=3)
     93                 continue;
     94             node_st p(node);
     95             p.map[node.xpos] = p.map[x*3+y];
     96             p.xpos = x*3+y;
     97             p.map[p.xpos] = 'x';
     98             can = cantor(p);
     99             if (visit[can])
    100                 continue;
    101             visit[can] = 1;
    102             ++p.s;
    103             p.p = p.s + h(p);
    104             pre[can] = pcan;
    105             op[can] = move[i];
    106             if (can == 0)
    107                 return ;
    108             que.push(p);
    109         }
    110     }
    111 }
    112 
    113 int main() {
    114     int i, k;
    115     stack<char> st;
    116 
    117     while (scanf("%c%*c", &beg.map[0]) != EOF) {
    118         for (i=0; i<N; ++i) {
    119             if (i)
    120                 scanf("%c%*c", &beg.map[i]);
    121             if (beg.map[i] == 'x')
    122                 beg.xpos = i;
    123         }
    124         beg.s = 0;
    125         beg.p = h(beg);
    126         if ( invNum(beg) ) {
    127             printf("unsolvable
    ");
    128             continue;
    129         }
    130         bcan = cantor(beg);
    131         if (bcan == 0) {
    132             printf("
    ");
    133             continue;
    134         }
    135         bfs();
    136         k = 0;
    137         while (k != bcan) {
    138             st.push(op[k]);
    139             k = pre[k];
    140         }
    141 
    142         while ( !st.empty() ) {
    143             printf("%c", st.top());
    144             st.pop();
    145         }
    146         printf("
    ");
    147     }
    148     return 0;
    149 }

    4. IDA*,该算法其实是迭代dfs。H函数还是曼哈顿距离。

      1 #include <iostream>
      2 #include <string>
      3 #include <cstdio>
      4 #include <cstring>
      5 using namespace std;
      6 
      7 #define N       9
      8 #define MAXN    362880
      9 
     10 typedef struct {
     11     char map[N];
     12     int xpos;
     13 } node_st;
     14 
     15 int fact[N] = {1,1,2,6,24,120,720,5040,40320};
     16 int direct[4][2] = {{-1,0},{1,0},{0,-1},{0,1}};
     17 char move[4] = {'u', 'd', 'l', 'r'};
     18 char visit[MAXN];
     19 char op[MAXN];
     20 int deep;
     21 bool flag;
     22 node_st beg;
     23 
     24 inline int cantor(node_st node) {
     25     int i, j, cnt, val = 0;
     26 
     27     for (i=0; i<N; ++i) {
     28         cnt = 0;
     29         for (j=i+1; j<N; ++j)
     30             if (node.map[j] < node.map[i])
     31                 ++cnt;
     32         val += fact[N-1-i]*cnt;
     33     }
     34 
     35     return val;
     36 }
     37 
     38 inline bool invNum(node_st node) {
     39     int i, j, cnt = 0;
     40 
     41     for (i=0; i<N; ++i) {
     42         if (node.map[i] == 'x') continue;
     43         for (j=i-1; j>=0; --j)
     44             if (node.map[j]!='x' && node.map[j]>node.map[i])
     45                 ++cnt;
     46     }
     47 
     48     return cnt&1;
     49 }
     50 
     51 inline int myabs(int x) {
     52     return (x<0) ? -x:x;
     53 }
     54 
     55 inline int h(node_st node) {
     56     int i, tmp, val = 0;
     57 
     58     for (i=0; i<N; ++i) {
     59         if (node.map[i] == 'x') continue;
     60         tmp = node.map[i] - '1';
     61         val += myabs(tmp/3-i/3) + myabs(tmp%3-i%3);
     62     }
     63 
     64     return val;
     65 }
     66 
     67 void dfs(int d) {
     68     int i, t1, t2, x, y, can;
     69 
     70     t1 = h(beg);
     71     if (t1 == 0) {
     72         flag = false;
     73         return ;
     74     }
     75     if (t1+d > deep)
     76         return ;
     77     t1 = beg.xpos / 3;
     78     t2 = beg.xpos % 3;
     79     for (i=0; i<4; ++i) {
     80         x = t1 + direct[i][0];
     81         y = t2 + direct[i][1];
     82         if (x<0 || x>=3 || y<0 || y>=3)
     83             continue;
     84         node_st p(beg), org(beg);
     85         p.map[p.xpos] = p.map[x*3+y];
     86         p.xpos = x*3+y;
     87         p.map[p.xpos] = 'x';
     88         can = cantor(p);
     89         if (visit[can]) continue;
     90         visit[can] = 1;
     91         op[d] = move[i];
     92         beg = p;
     93         dfs(d+1);
     94         if ( !flag )
     95             return ;
     96         beg = org;
     97         visit[can] = 0;
     98     }
     99 }
    100 
    101 int main() {
    102     int i;
    103 
    104     while (scanf("%c%*c", &beg.map[0]) != EOF) {
    105         for (i=0; i<N; ++i) {
    106             if (i)
    107                 scanf("%c%*c", &beg.map[i]);
    108             if (beg.map[i] == 'x')
    109                 beg.xpos = i;
    110         }
    111         if ( invNum(beg) ) {
    112             printf("unsolvable
    ");
    113             continue;
    114         }
    115         memset(visit, 0, sizeof(visit));
    116         memset(op, 0, sizeof(op));
    117         i = cantor(beg);
    118         visit[i] = 1;
    119         deep = h(beg);
    120         flag = true;
    121         while (flag) {
    122             ++deep;
    123             dfs(0);
    124             //printf("%d
    ", deep);
    125         }
    126 
    127         i = 0;
    128         while ( op[i] )
    129             printf("%c", op[i++]);
    130         printf("
    ");
    131     }
    132 
    133     return 0;
    134 }
  • 相关阅读:
    nowcoderD Xieldy And His Password
    Codeforces681D Gifts by the List
    nowcoder80D applese的生日
    Codeforces961E Tufurama
    Codeforces957 Mahmoud and Ehab and yet another xor task
    nowcoder82E 无向图中的最短距离
    nowcoder82B 区间的连续段
    Codeforces903E Swapping Characters
    Codeforces614C Peter and Snow Blower
    Codeforces614D Skills
  • 原文地址:https://www.cnblogs.com/bombe1013/p/3763767.html
Copyright © 2011-2022 走看看