• ACM/ICPC 之 BFS(离线)+康拓展开 (HDU1430-魔板)


      魔板问题,一道经典的康拓展开+BFS问题,为了实现方便,我用string类来表示字符串,此前很少用string类(因为不够高效,而且相对来说我对char数组的相关函数比较熟),所以在这里也发现了很多容易被忽视的问题。


      对于康拓展开不太熟系的可以先参看一篇博客:http://blog.csdn.net/zhongkeli/article/details/6966805

      

      关于sting类,大家要注意,在赋值的时候,其赋值位置不能与首位置间存在未赋值部分

      题目需要转换思路的地方是: 我们需要将起始魔板->目标魔板 转换为 标准魔板->新目标魔板的形式,以便离线(打表)一次就够了。

      具体代码如下:

      1 //魔板问题-BFS(离线)+康拓展开
      2 //Time: 38Ms Memory:6484K
      3 #include<iostream>
      4 #include<string>
      5 #include<queue>
      6 #include<algorithm>
      7 using namespace std;
      8 
      9 #define MAX 40321
     10 
     11 int fac[8] = { 1,1,2,6,24,120,720,5040 };    //阶乘数组
     12 
     13 int v[MAX];        //访问标记
     14 string ans[MAX];    //离线表
     15 
     16 struct Board{
     17     int val;    //Hash值
     18     string str;
     19 };
     20 
     21 //康拓展开(Hash)
     22 int Contor(string str)
     23 {
     24     int num = 0;    //Hash值
     25     for (int i = 0; i < 8; i++)
     26     {
     27         int tmp = 0;    //在此后的序列中的位置(升序)
     28         for (int j = i + 1; j < 8; j++)
     29             if (str[j] < str[i]) tmp++;
     30         num += tmp*fac[7 - i];
     31     }
     32     return num;
     33 }
     34 
     35 //离线打表(BFS)
     36 void Init()
     37 {
     38     queue<Board>Q;
     39     Board t, tmp;
     40     t.str = tmp.str = "12345678";    //初始数组
     41     t.val = Contor(t.str);
     42     v[t.val] = 1;
     43     Q.push(t);
     44     while (!Q.empty()) {
     45         t = Q.front();
     46         Q.pop();
     47 
     48         // A:交换行
     49         for (int i = 0; i < 8; i++)
     50             tmp.str[(i + 4) % 8] = t.str[i];
     51 
     52         tmp.val = Contor(tmp.str);
     53         if (!v[tmp.val]) {
     54             v[tmp.val] = 1;
     55             ans[tmp.val] = ans[t.val] + 'A';
     56             Q.push(tmp);
     57         }
     58 
     59         // B:循环右移
     60         for (int i = 0; i < 4; i++)
     61             tmp.str[(i + 1) % 4] = t.str[i];
     62         for (int i = 4; i < 8; i++)
     63             tmp.str[(i + 1) % 4 + 4] = t.str[i];
     64 
     65         tmp.val = Contor(tmp.str);
     66         if (!v[tmp.val]) {
     67             v[tmp.val] = 1;
     68             ans[tmp.val] = ans[t.val] + 'B';
     69             Q.push(tmp);
     70         }
     71 
     72         // C:中心顺时旋转
     73         tmp.str = t.str;
     74         tmp.str[1] = t.str[5]; tmp.str[2] = t.str[1];
     75         tmp.str[6] = t.str[2]; tmp.str[5] = t.str[6];
     76 
     77         tmp.val = Contor(tmp.str);
     78         if (!v[tmp.val]) {
     79             v[tmp.val] = 1;
     80             ans[tmp.val] = ans[t.val] + 'C';
     81             Q.push(tmp);
     82         }
     83     }
     84 }
     85 
     86 int main()
     87 {
     88     Init();    //BFS
     89     string ts, te;
     90     while (cin >> ts >> te)
     91     {
     92         /*转换成顺序魔板*/
     93         swap(ts[5], ts[6]);
     94         swap(ts[4], ts[7]);
     95         swap(te[5], te[6]);
     96         swap(te[4], te[7]);
     97 
     98         /*将起始魔板转换为标准魔板,相应目标魔板也进行变更*/
     99         char tmp[9];
    100         for (int i = 0; i < 8; i++)
    101             tmp[ts[i] - '0'] = i + '1';
    102         for (int i = 0; i < 8; i++)
    103             te[i] = tmp[te[i] - '0'];
    104 
    105         cout << ans[Contor(te)] << endl;
    106     }
    107 
    108     return 0;
    109 }
    他坐在湖边,望向天空,她坐在对岸,盯着湖面
  • 相关阅读:
    回来了
    【Docker】Docker学习笔记:shipyard使用
    【Docker】Docker学习笔记:安装部署
    【LVS】LVS用windows作为realserver的设置方法
    【linux常用命令】linux命令工具基础
    【linux工具】crontab
    【开源软件】windows环境下libcurl编译
    【工作笔记】CPU亲和性
    【转】多线程or多进程
    【学习笔记】git常用命令
  • 原文地址:https://www.cnblogs.com/Inkblots/p/5087550.html
Copyright © 2020-2023  润新知