zoukankan      html  css  js  c++  java
  • noip2013 华容道

    题目描述

    【问题描述】

    小 B 最近迷上了华容道,可是他总是要花很长的时间才能完成一次。于是,他想到用编程来完成华容道:给定一种局面, 华容道是否根本就无法完成,如果能完成, 最少需要多少时间。

    小 B 玩的华容道与经典的华容道游戏略有不同,游戏规则是这样的:

    1. 在一个 n*m 棋盘上有 n*m 个格子,其中有且只有一个格子是空白的,其余 n*m-1个格子上每个格子上有一个棋子,每个棋子的大小都是 1*1 的;

    2. 有些棋子是固定的,有些棋子则是可以移动的;

    3. 任何与空白的格子相邻(有公共的边)的格子上的棋子都可以移动到空白格子上。

    游戏的目的是把某个指定位置可以活动的棋子移动到目标位置。

    给定一个棋盘,游戏可以玩 q 次,当然,每次棋盘上固定的格子是不会变的, 但是棋盘上空白的格子的初始位置、 指定的可移动的棋子的初始位置和目标位置却可能不同。第 i 次

    玩的时候, 空白的格子在第 EXi 行第 EYi 列,指定的可移动棋子的初始位置为第 SXi 行第 SYi列,目标位置为第 TXi 行第 TYi 列。

    假设小 B 每秒钟能进行一次移动棋子的操作,而其他操作的时间都可以忽略不计。请你告诉小 B 每一次游戏所需要的最少时间,或者告诉他不可能完成游戏。

    输入输出格式

    输入格式:

     

    输入文件为 puzzle.in。

    第一行有 3 个整数,每两个整数之间用一个空格隔开,依次表示 n、m 和 q;

    接下来的 n 行描述一个 n*m 的棋盘,每行有 m 个整数,每两个整数之间用一个空格隔开,每个整数描述棋盘上一个格子的状态,0 表示该格子上的棋子是固定的,1 表示该格子上的棋子可以移动或者该格子是空白的。接下来的 q 行,每行包含 6 个整数依次是 EXi、EYi、SXi、SYi、TXi、TYi,每两个整数之间用一个空格隔开,表示每次游戏空白格子的位置,指定棋子的初始位置和目标位置。

     

    输出格式:

     

    输出文件名为 puzzle.out。

    输出有 q 行,每行包含 1 个整数,表示每次游戏所需要的最少时间,如果某次游戏无法完成目标则输出−1。

     

    输入输出样例

    输入样例#1:
    3 4 2
    0 1 1 1
    0 1 1 0
    0 1 0 0
    3 2 1 2 2 2
    1 2 2 2 3 2
    输出样例#1:
    2
    -1

    说明

    【输入输出样例说明】

    棋盘上划叉的格子是固定的,红色格子是目标位置,圆圈表示棋子,其中绿色圆圈表示目标棋子。

    1. 第一次游戏,空白格子的初始位置是 (3, 2)(图中空白所示),游戏的目标是将初始位置在(1, 2)上的棋子(图中绿色圆圈所代表的棋子)移动到目标位置(2, 2)(图中红色的格子)上。

    移动过程如下:

    1. 第二次游戏,空白格子的初始位置是(1, 2)(图中空白所示),游戏的目标是将初始位置在(2, 2)上的棋子(图中绿色圆圈所示)移动到目标位置 (3, 2)上。

    要将指定块移入目标位置,必须先将空白块移入目标位置,空白块要移动到目标位置,必然是从位置(2, 2)上与当前图中目标位置上的棋子交换位置,之后能与空白块交换位置的只有当前图中目标位置上的那个棋子,因此目标棋子永远无法走到它的目标位置, 游戏无

    法完成。

    【数据范围】

    对于 30%的数据,1 ≤ n, m ≤ 10,q = 1;

    对于 60%的数据,1 ≤ n, m ≤ 30,q ≤ 10;

    对于 100%的数据,1 ≤ n, m ≤ 30,q ≤ 500。

    solution


    暴力(70):

    定义f[x1][y1][x2][y2]为空格在(x1,y1),目标棋子在(x2,y2),时的最小步数

    之后bfs就行

    正解:

    也是bfs

    预处理出来数组 g[x][y][k][kk]  1<=k,kk<=4

    意义是 当前棋子在(x,y)白棋子在k方向(上下左右),想要走到kk方向的最小步数

    之后对于每次询问

    首先把白格子挪到目标旗子周围,之后把目标棋子挪到目标位置,bfs利用g[][][][]数组

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<iostream>
      4 #include<queue>
      5 #define mem(a,b) memset(a,b,sizeof(a))
      6 using namespace std;
      7 const int DUI=20000006;
      8 const int INF=0x7fffffff;
      9 
     10 inline int minn(int a,int b){return a<b?a:b;}
     11 
     12 struct Queue
     13 {
     14     int x,y;
     15 };
     16 
     17 queue<Queue> q;
     18 int n,m,Q,qqq;
     19 int bx[6]={0,-1,1,0,0,0};
     20 int by[6]={0,0,0,-1,1,0};// 1 上 2 下 3 左 4 右 
     21 int f[36][36][6],ha[6],flag[36][36],vis[36][36][6];
     22 int a[36][36],g[36][36][6][6],d[36][36];
     23 int whx,why,sx,sy,tx,ty;
     24 
     25 void out11();
     26 
     27 void chu()
     28 {
     29     mem(g,60);
     30     qqq=g[0][0][0][0];
     31     Queue now;
     32     int x,y;
     33     for(int i=1;i<=n;++i)
     34       for(int j=1;j<=m;++j)
     35       {
     36           if(a[i][j]==0)
     37             continue;
     38         for(int bai=1;bai<=4;++bai)
     39         {//printf("saafsffas
    ");
     40                 if( (i+bx[bai]<1) || (i+bx[bai]>n) || (j+by[bai]<1) || (j+by[bai]>m) || (a[i+bx[bai]][j+by[bai]]==0) )
     41                   continue;
     42           for(int tt=1;tt<=4;++tt)
     43           {
     44                     if( (i+bx[tt]<1) || (i+bx[tt]>n) || (j+by[tt]<1) || (j+by[tt]>m) || (a[i+bx[tt]][j+by[tt]]==0) )
     45                       continue;
     46                     //printf("i=%d j=%d
    ",i,j);
     47                     if(bai==tt)
     48                     {
     49                         g[i][j][bai][tt]=0;
     50                       continue;
     51                     }
     52                     
     53                     
     54                     
     55                     while(!q.empty())q.pop();
     56                     mem(d,60);mem(flag,0);
     57                     sx=i+bx[bai];sy=j+by[bai];
     58                     tx=i+bx[tt];ty=j+by[tt];
     59                     d[sx][sy]=0;flag[sx][sy]=1;
     60                     q.push((Queue){sx,sy});
     61                     while(!q.empty())
     62                     {
     63             
     64                         now=q.front();q.pop();
     65                         x=now.x;y=now.y;flag[x][y]=0;
     66                         //if(x==tx&&y==ty)
     67                         //  break;
     68                         
     69                         for(int k=1;k<=4;++k)
     70                         {
     71                             if(x+bx[k]<1||x+bx[k]>n||y+by[k]<1||y+by[k]>m||a[x+bx[k]][y+by[k]]==0|| (x+bx[k]==i&&y+by[k]==j) )
     72                               continue;
     73                             //printf("sdasdasd
    ");
     74                             if(d[x+bx[k]][y+by[k]]>d[x][y]+1)
     75                             {
     76                                 d[x+bx[k]][y+by[k]]=d[x][y]+1;
     77                                 if(!flag[x+bx[k]][y+by[k]])
     78                                 {
     79                                     q.push((Queue){x+bx[k],y+by[k]});
     80                                     flag[x+bx[k]][y+by[k]]=1;
     81                                 }
     82                             }
     83                         }
     84                     }
     85                     
     86                     //g[i][j][bai][tt]=d[tx][ty]+1;
     87                     g[i][j][bai][tt]=d[tx][ty];
     88                     
     89                     //out11();
     90                     
     91                     //printf("i=%d j=%d k=%d l=%d g[][][][]=%d
    ",i,j,bai,tt,g[i][j][bai][tt]);
     92                 }
     93             }
     94         }
     95 }// yes
     96 
     97 int bfs1()
     98 {
     99     Queue now;
    100     int x,y;
    101     mem(d,60);
    102     while(!q.empty())q.pop();
    103     mem(flag,0);
    104     d[whx][why]=0;flag[whx][why]=1;
    105     q.push((Queue){whx,why});
    106     while(!q.empty())
    107     {
    108         now=q.front();q.pop();
    109         x=now.x;y=now.y;flag[x][y]=0;
    110         for(int k=1;k<=4;++k)
    111         {
    112             if(x+bx[k]<1||x+bx[k]>n||y+by[k]<1||y+by[k]>m||a[x+bx[k]][y+by[k]]==0|| (x+bx[k]==sx&&y+by[k]==sy) )
    113               continue;
    114             if(d[x+bx[k]][y+by[k]]>d[x][y]+1)
    115             {
    116                 d[x+bx[k]][y+by[k]]=d[x][y]+1;
    117                 if(!flag[x+bx[k]][y+by[k]])
    118                 {
    119                     q.push((Queue){x+bx[k],y+by[k]});
    120                     flag[x+bx[k]][y+by[k]]=1;
    121                 }
    122             }
    123         }
    124     }
    125     
    126     for(int i=1;i<=4;++i)
    127       if(d[sx+bx[i]][sy+by[i]]<qqq)
    128         return 1;
    129     return 0;
    130 }
    131 
    132 struct son
    133 {
    134     int x,y,k;
    135 };
    136 queue<son> dui;
    137 
    138 int bfs2()
    139 {
    140     son now;
    141     int x,y,nowk;
    142     mem(f,60);mem(vis,0);
    143     for(int i=1;i<=4;++i)
    144     {
    145       if(sx+bx[i]<1||sx+bx[i]>n||sy+by[i]<1||sy+by[i]>m||a[sx+bx[i]][sy+by[i]]==0||d[sx+bx[i]][sy+by[i]]==qqq)
    146         continue;
    147       f[sx][sy][i]=d[sx+bx[i]][sy+by[i]];
    148       vis[sx][sy][i]=1;
    149       //printf("ssdad=%d
    ",d[sx+bx[i]][sy+by[i]]);
    150       dui.push((son){sx,sy,i});
    151     }
    152     
    153     //out11();
    154     
    155     while(!dui.empty())
    156     {
    157         now=dui.front();dui.pop();
    158         x=now.x;y=now.y;nowk=now.k;
    159         vis[x][y][nowk]=0;
    160         
    161         for(int i=1;i<=4;++i)
    162         {
    163             if(x+bx[i]<1|| (x+bx[i]>n) || (y+by[i]<1) || (y+by[i]>m) || (a[x+bx[i]][y+by[i]]==0) )
    164               continue;
    165             //printf("hhahahahahha
    ");
    166             int temp1=f[x+bx[i]][y+by[i]][ha[i]];
    167             int temp2=f[x][y][nowk]+1+g[x][y][nowk][i];
    168             //printf("%d %d
    ",temp1,temp2);
    169             if(temp1>temp2)
    170             {
    171                 
    172                 f[x+bx[i]][y+by[i]][ha[i]]=f[x][y][nowk]+1+g[x][y][nowk][i];
    173                 if(!vis[x+bx[i]][y+by[i]][ha[i]])//////????????
    174                 {
    175                     dui.push((son){x+bx[i],y+by[i],ha[i]});
    176                     vis[x+bx[i]][y+by[i]][ha[i]]=1;
    177                 }
    178             }
    179         }
    180     }
    181     
    182     //out11();
    183     
    184     int ans=INF;
    185     for(int i=1;i<=4;++i)
    186       ans=minn(ans,f[tx][ty][i]);
    187     return ans;
    188 }
    189 
    190 void out11()
    191 {
    192     printf("
    ");
    193     for(int k=1;k<=4;++k)
    194     {
    195     for(int i=1;i<=n;++i)
    196     {
    197       for(int j=1;j<=m;++j)
    198         printf("%d ",f[i][j][k]);
    199       printf("
    ");
    200     }
    201     printf("
    ");
    202   }
    203   
    204     /*for(int i=1;i<=n;++i)
    205     {
    206     for(int j=1;j<=m;++j)
    207       printf("%d ",d[i][j]);
    208     printf("
    ");
    209   }*/
    210     /*for(int i=1;i<=n;++i)
    211       for(int j=1;j<=m;++j)
    212         for(int k=1;k<=4;++k)
    213           for(int l=1;l<=4;++l)
    214             if(g[i][j][k][l]!=qqq)
    215               printf("i=%d j=%d k=%d l=%d g[][][][]=%d
    ",i,j,k,l,g[i][j][k][l]);*/
    216     printf("
    ");
    217 }
    218 
    219 int main(){
    220     
    221     //freopen("1.txt","r",stdin);
    222     
    223     scanf("%d%d%d",&n,&m,&Q);
    224     for(int i=1;i<=n;++i)
    225       for(int j=1;j<=m;++j)
    226         scanf("%d",&a[i][j]);
    227     chu();
    228     ha[1]=2;ha[2]=1;ha[3]=4;ha[4]=3;
    229     
    230     //out11();
    231     
    232     while(Q--)
    233     {
    234         scanf("%d%d%d%d%d%d",&whx,&why,&sx,&sy,&tx,&ty);
    235         if(sx==tx&&sy==ty)
    236         {
    237             printf("0
    ");
    238             continue;
    239         }
    240         if(bfs1()==0)
    241         {
    242             printf("-1
    ");
    243             continue;
    244         }
    245         int temp=bfs2();
    246         if(temp>=qqq)
    247         {
    248             printf("-1
    ");
    249             continue;
    250         }
    251         printf("%d
    ",temp);
    252     }
    253     
    254     //while(1);
    255     return 0;
    256 }
    code
  • 相关阅读:
    使用grpc C++功能
    华为任正非访谈
    苹果产品
    异步编程
    基于磁盘存储
    spring 应用
    java简单框架设计
    消息队列架构
    03 java 基础:注释 关键字 标识符 JShell
    02 java 基础:java 文件名与类名关系 CLASSPATH
  • 原文地址:https://www.cnblogs.com/A-LEAF/p/7403665.html
Copyright © 2011-2022 走看看