zoukankan      html  css  js  c++  java
  • 【noip 2014】提高组Day2T3.华容道

    Description

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

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

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

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

    3.任何与空白的格子相邻(有公共的边)的格子上的棋子都可以移动到空白格子上。 游戏的目的是把某个指定位置可以活动的棋子移动到目标位置。

    给定一个棋盘,游戏可以玩 q 次,当然,每次棋盘上固定的格子是不会变的,但是棋盘上空白的格子的初始位置、指定的可移动的棋子的初始位置和目标位置却可能不同。第 i 次玩的时候,空白的格子在第EXi行EYi列,指定的可移动棋子的初始位置为第SXi行第SYi​​ 列,目标位置为第TXi​​ 行第TYi​​列。

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

    Input

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

    接下来的 n 行描述一个 n*m 的棋盘,每行有 m 个整数,每两个整数之间用一个空格隔开,每个整数描述棋盘上一个格子的状态,0 表示该格子上的棋子是固定的,1 表示该格子上的棋子可以移动或者该格子是空白的。

    接下来的 q 行,每行包含 6 个整数依次是EXi、EYi、SXi、SYi、TXi、TYi,每两个整数之间用一个空格隔开,表示每次游戏空白格子的位置,指定棋子的初始位置和目标位置。

    Output

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

    Sample Input

    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

    Sample Output

    2
    -1

    讲道理,这题的预处理真的不是来恶心人的吗TAT

    一篇比较资磁的题解

    然后有一个小技巧:用1代表上,2代表左,3代表右,4代表下,则a的反方向就是5-a。

    存一存代码。

      1 #include<cstdio>
      2 #include<algorithm>
      3 #include<cstring>
      4 #include<queue>
      5 using namespace std;
      6 const int inf=0x3f3f3f3f;
      7 int n,m,k,ex,ey,sx,sy,tx,ty,ans;
      8 int map[35][35],deep[35][35],dis[35][35][5],mov[35][35][5][5];
      9 bool d[35][35],in[35][35][5];
     10 struct node{int x,y,k;}t1,t2;
     11 int read()
     12 {
     13     int x=0,f=1;char c=getchar();
     14     while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
     15     while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
     16     return x*f;
     17 }
     18 node move(node t,int k)
     19 {
     20     if(k==1)t.x--;if(k==2)t.y--;
     21     if(k==3)t.y++;if(k==4)t.x++;
     22     return t;
     23 }
     24 int bfs(node s,node t)
     25 {
     26     node now,to;
     27     memset(deep,0x3f,sizeof(deep));
     28     memset(d,0,sizeof(d));
     29     queue<node>q;q.push(s);
     30     deep[s.x][s.y]=0;d[s.x][s.y]=true;
     31     while(!q.empty()&&!d[t.x][t.y])
     32     {
     33         now=q.front();q.pop();
     34         for(int k=1;k<=4;k++)
     35         {
     36             to=move(now,k);
     37             if(!d[to.x][to.y]&&map[to.x][to.y]==1)
     38             {
     39                 d[to.x][to.y]=true;q.push(to);
     40                 deep[to.x][to.y]=deep[now.x][now.y]+1;
     41             }
     42         }
     43     }
     44     return deep[t.x][t.y];
     45 }
     46 void init()
     47 {
     48     memset(mov,0x3f,sizeof(mov));
     49     for(int i=1;i<=n;i++)
     50         for(int j=1;j<=m;j++)
     51         {
     52             if(map[i][j]==0)continue;
     53             map[i][j]=0;
     54             for(int k=1;k<=4;k++)
     55                 for(int l=1;l<=4;l++)
     56                 {
     57                     if(l<k){mov[i][j][k][l]=mov[i][j][l][k];continue;}
     58                     t1=move((node){i,j,k},k);t2=move((node){i,j,l},l);
     59                     if(map[t1.x][t1.y]==0||map[t2.x][t2.y]==0)continue;
     60                     mov[i][j][k][l]=bfs(t1,t2)+1;
     61                 }
     62             map[i][j]=1;
     63         }
     64 }
     65 void spfa(node s,node t)
     66 {
     67     ans=inf;
     68     if(s.x==t.x&&s.y==t.y){ans=0;return;}
     69     if(map[s.x][s.y]==0||map[t.x][t.y]==0)return;
     70     node now,to;
     71     memset(dis,0x3f,sizeof(dis));
     72     memset(in,0,sizeof(in));
     73     queue<node>q;
     74     map[s.x][s.y]=0;
     75     for(int i=1;i<=4;i++)
     76     {
     77         q.push((node){s.x,s.y,i});
     78         in[s.x][s.y][i]=true;
     79         dis[s.x][s.y][i]=bfs((node){ex,ey,0},move(s,i));
     80     }
     81     map[s.x][s.y]=1;
     82     while(!q.empty())
     83     {
     84         now=q.front();q.pop();
     85         in[now.x][now.y][now.k]=false;
     86         for(int i=1;i<=4;i++)
     87         {
     88             to=move(now,i);to.k=5-i;
     89             if(dis[now.x][now.y][now.k]+mov[now.x][now.y][now.k][i]<dis[to.x][to.y][5-i])
     90             {
     91                 dis[to.x][to.y][5-i]=dis[now.x][now.y][now.k]+mov[now.x][now.y][now.k][i];
     92                 if(!in[to.x][to.y][to.k])q.push(to),in[to.x][to.y][to.k]=true;
     93             }
     94         }
     95     }
     96     for(int i=1;i<=4;i++)ans=min(ans,dis[t.x][t.y][i]);
     97 }
     98 int main()
     99 {
    100     n=read();m=read();k=read();
    101     for(int i=1;i<=n;i++)
    102         for(int j=1;j<=m;j++)
    103             map[i][j]=read();
    104     init();
    105     for(int i=1;i<=k;i++)
    106     {
    107         ex=read();ey=read();sx=read();sy=read();tx=read();ty=read();
    108         spfa((node){sx,sy,0},(node){tx,ty,0});
    109         if(ans==inf)printf("-1
    ");
    110         else printf("%d
    ",ans);
    111     }
    112     return 0;
    113 }
    View Code
  • 相关阅读:
    java.security.InvalidKeyException: Illegal key size aes解密失败
    Java获取URL链接的文件类型
    解决eclipse中web项目出现Project facet Java version 1.8 is not supported.的问题
    探讨一下Java单例设计模式
    HTML5文件上传qq、百度、taobao等比较(改进支持三种状态提示)
    jQuery Ajax 上传文件改进
    Java POI 3.17写入、导入EXCEL性能测试
    jQuery Ajax 上传文件夹及文件
    Java 打包下载服务器上选中的文件或目录(带进度条提示)
    pio 背景色
  • 原文地址:https://www.cnblogs.com/zsnuo/p/7256787.html
Copyright © 2011-2022 走看看