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 }
  • 相关阅读:
    day01-h1字体大小和文本居中
    js正则表达式中的
    js滚动分页原理
    在web.xml中设置全局编码
    C# 导出word 表格代码
    C# 创建单例
    Winform 异步调用2 时间
    Winform 异步调用
    c#中跨线程调用windows窗体控件
    C# 中的委托和事件
  • 原文地址:https://www.cnblogs.com/bombe1013/p/3763767.html
Copyright © 2011-2022 走看看