• HDU 4531 bfs/康拓展开


    题目链接http://acm.hdu.edu.cn/showproblem.php?pid=4531

    吉哥系列故事——乾坤大挪移

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)
    Total Submission(s): 555    Accepted Submission(s): 178


    Problem Description
      只有进入本次马拉松复赛,你才有机会知道一个秘密:吉哥的真名叫基哥,江湖人称“叽叽哥”。

      叽叽哥除了编程,还一直有个武侠梦,他最喜欢的人物是金庸小说《倚天屠龙记》中的张无忌,不仅有美人环绕,而且有一身的好武功,尤其是那神秘的乾坤大挪移,让他梦寐以求:
      
      “乾坤大挪移乃在颠倒一刚一柔、一阴一阳的乾坤二气,随意而行,不用心而无不心用,所谓至我逍遥游,以纯阳之身,和纯阴之体,合练双修,不动身,只用意,意动身守......”
      
      但是,梦毕竟只是梦,平时在编程的空闲时间,叽叽哥也最多只能上网玩一下名为“乾坤大挪移”的游戏聊以自慰而已。
      这个“乾坤大挪移”游戏是在3*3的方格中进行。
      游戏的目标是通过移动,让相同颜色的块形成一个连通块(相邻是指两个块有边相邻,角相邻不算)。
      移动规则如下:选择一行(列),向左右(上下)移动一格,方格从一边划出,则从对应的另外一边划入,像履带一样。
      如选择第一行向右边移动,最右边的那格会移动到最左边。
      游戏中还有一些方格被固定住,这些方格没办法移动(如下图的第三行第二列)。
      下图是游戏的一个演示(即Case 1):



      假设现在告诉你初始状态,请问你最少需要几步才能达到目标?
     
    Input
    第一行一个整数T代表接下去有T组数据;
    每组数据由3*3的模块组成,每个模块表示的小正方形是由上下左右四个小三角形组成;
    每个模块有5个字符,前四个字符分别表示组成正方形的上下左右四个小三角形的颜色,第五个字符表示该格子能否移动(0表示能移动,1表示不能移动).

    [Technical Specification]
    0<T<=100
    代表颜色的字符一定是RGBO的其中一个
    代表能否移动移动的字符一定是0或者1
     
    Output
    首先输出case数,接着输出最小的移动步数使得游戏达到目标状态(见sample);
    数据保证有解。
     
    Sample Input
    2 GGGG0 GGGG0 GGGG0 OGOO0 GGGG0 OGOO0 OOOO0 OGGG1 OOOO0 RRRR0 OOOO0 OOOO0 OOOO0 OOOO0 OOOO0 OOOO0 OOOO0 RRRR0
     
    Sample Output
    Case #1: 5 Case #2: 2
     
    Source
     看到题目,确实感觉有点麻烦,很考验代码能力,代码能力差的话可能要写很长的代码,容易犯错。
    首先类似于八数码问题的棋盘规格,我们考虑使用康拓展开作为状态压缩标记走过的棋盘样式,最多9!种状态。
    节点保存棋盘压缩值,步数,棋盘样式。为了方便将每个方格内的四个三角分别对应0,1,2,3,那么a[i][j][k]就可以方便的表示i行j列第k个三角。
    每次检查当前头部节点对应的棋盘是否达到了目标状态。这个听别人用的并查集,我没有用,我是dfs染色统计每个颜色联通快的个数,如果每个颜色的个数都<=1,说明当前就是一个合法的状态。关键就是dfs时的方向问题困扰了我,我们常见的方形棋盘一般就是4/8个直观的方形,这个却是三角,其实也不是很难,我们只要dfs三角形的三条边不就好了吗,一共四种三角分类讨论一下也就好了。最后就是有12种移动方式,简单的交换一下就好了,注意提前判断一下是否有不可移动的格子。
      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 bool vis[3630000];
      4 int f[15]={1,1,2,6,24,120,720,5040,40320,362880};
      5 struct node
      6 {
      7     int cal,bs;
      8     char e[10];
      9 };
     10 void change1(node &t,int type)
     11 {
     12     switch(type)
     13     {
     14         case 1:swap(t.e[0],t.e[1]);swap(t.e[1],t.e[2]);break;
     15         case 2:swap(t.e[1],t.e[2]);swap(t.e[0],t.e[1]);break;
     16         case 3:swap(t.e[3],t.e[4]);swap(t.e[4],t.e[5]);break;
     17         case 4:swap(t.e[4],t.e[5]);swap(t.e[3],t.e[4]);break;
     18         case 5:swap(t.e[6],t.e[7]);swap(t.e[7],t.e[8]);break;
     19         case 6:swap(t.e[7],t.e[8]);swap(t.e[6],t.e[7]);break;
     20         case 7:swap(t.e[0],t.e[3]);swap(t.e[3],t.e[6]);break;
     21         case 8:swap(t.e[3],t.e[6]);swap(t.e[0],t.e[3]);break;
     22         case 9:swap(t.e[1],t.e[4]);swap(t.e[4],t.e[7]);break;
     23         case 10:swap(t.e[4],t.e[7]);swap(t.e[1],t.e[4]);break;
     24         case 11:swap(t.e[2],t.e[5]);swap(t.e[5],t.e[8]);break;
     25         case 12:swap(t.e[5],t.e[8]);swap(t.e[2],t.e[5]);break;
     26     }
     27 
     28 }
     29 int cal(node A)
     30 {
     31     int s=0,i,j;
     32     for(i=0;i<9;++i)
     33     {
     34         int c=0;
     35         for(j=i+1;j<9;++j)
     36             if(A.e[j]<A.e[i]) c++;
     37         s+=c*f[8-i];
     38     }
     39     return s;
     40 }
     41 struct nic
     42 {
     43     char color[5];
     44 }a[4][4],b[4][4];
     45 bool mov[2][4];
     46 bool book[5][5][5];
     47 void dfs(int x,int y,int is,char clo)
     48 {
     49   if(x<1||y<1||x>3||y>3||is<0||is>3||b[x][y].color[is]!=clo||book[x][y][is]) return;
     50   b[x][y].color[is]='X';
     51   book[x][y][is]=1;
     52   if(is==0){
     53     dfs(x-1,y,2,clo);
     54     dfs(x,y,1,clo);
     55     dfs(x,y,3,clo);
     56   }
     57   else if(is==1){
     58     dfs(x,y+1,3,clo);
     59     dfs(x,y,0,clo);
     60     dfs(x,y,2,clo);
     61   }
     62   else if(is==2){
     63   dfs(x+1,y,0,clo);
     64   dfs(x,y,1,clo);
     65   dfs(x,y,3,clo);
     66   }
     67   else{
     68     dfs(x,y-1,1,clo);
     69     dfs(x,y,0,clo);
     70     dfs(x,y,2,clo);
     71   }
     72 }
     73 bool ok(node A)
     74 {
     75     int G=0,B=0,R=0,O=0,i,j,k,p=0;
     76     for(i=1;i<=3;++i)
     77         for(j=1;j<=3;++j,p++){
     78         int di=((int)(A.e[p]-'0'))/3+1,dj=((int)(A.e[p]-'0'))%3+1;
     79         for(k=0;k<4;++k)
     80             b[i][j].color[k]=a[di][dj].color[k];
     81         }
     82     for(i=1;i<=3;++i)
     83         for(j=1;j<=3;++j)
     84             for(k=0;k<4;++k)
     85             {
     86               if(b[i][j].color[k]=='G')
     87                 {G++;}
     88               else if(b[i][j].color[k]=='B')
     89                 B++;
     90               else if(b[i][j].color[k]=='R')
     91                 R++;
     92               else if(b[i][j].color[k]=='O')
     93                 O++;
     94               else continue;
     95                 memset(book,0,sizeof(book));
     96                 dfs(i,j,k,b[i][j].color[k]);
     97             }
     98     return (G<=1&&B<=1&&R<=1&&O<=1);
     99 }
    100 int bfs()
    101 {
    102     queue<node>Q;
    103     memset(vis,0,sizeof(vis));
    104     node t1,t2;
    105     t1.cal=0;
    106     t1.bs=0;
    107     strcpy(t1.e,"012345678");
    108     ok(t1);
    109     Q.push(t1);
    110     while(!Q.empty()){
    111         t1=Q.front();Q.pop();
    112         if(ok(t1)) {return t1.bs;}
    113         if(vis[t1.cal]) continue;
    114         vis[t1.cal]=1;
    115         for(int i=1;i<=12;++i)
    116         {
    117            if(i<=6&&mov[0][(i+1)/2]) continue;
    118            if(i>6&&mov[1][(i+1)/2-3]) continue;
    119             node tmp=t1;
    120             tmp.bs++;
    121             change1(tmp,i);
    122             tmp.cal=cal(tmp);
    123             if(!vis[tmp.cal]) Q.push(tmp);
    124         }
    125     }
    126     return -1;
    127 }
    128 int main()
    129 {
    130     int T,N,M,i,j,cas=0,n,m,k;
    131     int index[4]={0,2,3,1};
    132     cin>>T;
    133     while(T--){
    134         memset(mov,0,sizeof(mov));
    135         memset(a,0,sizeof(a));
    136         for(i=1;i<=3;++i)
    137            for(j=1;j<=3;++j)
    138            {
    139                for(k=0;k<4;++k)
    140                 cin>>a[i][j].color[index[k]];
    141             scanf("%d",&m);
    142             if(m==1) mov[0][i]=mov[1][j]=1;
    143            }
    144         printf("Case #%d: %d
    ",++cas,bfs());
    145     }
    146     return 0;
    147 }
  • 相关阅读:
    OpenCV 立体匹配 (自带程序)
    OpenCV 双目标定 ( 自带的例子)
    容器
    OpenCV 多边形逼近
    C++ 读取文件
    OpenCV 快速连通区域分析
    图像任意旋转
    OpenCV 模板匹配函数matchTemplate详解
    二十一:scrapy中设置下载延时与自动限速
    二十、scrapy中的Request对象和Response对象
  • 原文地址:https://www.cnblogs.com/zzqc/p/7358339.html
Copyright © 2020-2023  润新知