zoukankan      html  css  js  c++  java
  • hdu 1253 胜利大逃亡

      题目链接:hdu 1253,题目大意:从一个立方体的左下角走到右上角(两点间的连线为长方体的体对角线)的最少时间(步数),走不到或者最少时间达不到要求输出 -1,否则输出该时间。

      因为要求"最少"之类的,所以很容易想到广搜,没错,这是 bfs 的裸题,只是它的状态数是个三维数组,转移的状态(方向)也从二维数组的4个变成了6个而已,但原理是一样的,直接广搜即可,只是这题的坑未免也太不人性化了,我 wa了几发看了讨论区后才知道原来起点不管是不是墙都不用管(继续搜),只需看终点即可。

      首先是第一个版本的代码,用个三维的 dp 数组来记录从起点出发到当前结点的时间/步数,比较清晰:

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<cstdlib>
     4 #include<queue>
     5 using namespace std;
     6 #define For(i,s,t)    for(int i=s; i<t; ++i)
     7 const int inf= 0x2fffffff;
     8 int a,b,c,T;
     9 int f[60][60][60], dp[60][60][60];
    10 
    11 int dir[8][3]= {{0,0,1},{0,1,0},{-1,0,0},{1,0,0},{0,-1,0},{0,0,-1}};
    12 
    13 struct node{
    14     int x,y,z;
    15     node(int x=0, int y=0, int z=0): x(x),y(y),z(z) {}
    16 };
    17 
    18 void solve(){
    19     scanf("%d%d%d%d",&a,&b,&c,&T);
    20     For(i,0,a+2)    For(j,0,b+2)    For(k,0,c+2) {
    21         f[i][j][k]= 1;    dp[i][j][k]= inf;
    22     }
    23     For(i,1,a+1)    For(j,1,b+1)    For(k,1,c+1)
    24         scanf("%d",f[i][j]+k);
    25     
    26     //如果终点是墙就永远出不了,(这题挺坑的,起点不管是不是墙都不要紧) 
    27     //或者从起点到终点的最短直线距离比 T大的话也出不了,是个很重要的剪枝 
    28     if(f[a][b][c]==1 || a+b+c-3 > T)    {    puts("-1");     return ;    }
    29 
    30     queue<node> q;
    31     q.push(node(1,1,1));
    32     dp[1][1][1]= 0;
    33     while(q.size()){
    34         node p= q.front();    q.pop();
    35         for(int k=0; k<6; ++k){
    36             int dx= p.x+dir[k][0], dy= p.y+dir[k][1], dz= p.z+dir[k][2];
    37             if(f[dx][dy][dz]!= 1 && dp[dx][dy][dz]== inf){
    38                 dp[dx][dy][dz]= dp[p.x][p.y][p.z]+1;
    39                 q.push(node(dx,dy,dz));
    40             }
    41         }
    42     }
    43     //算出到达终点的时间后,还需判断是否满足题意 
    44     if(dp[a][b][c] > T)      puts("-1");
    45     else    printf("%d
    ",dp[a][b][c]);
    46 }
    47 
    48 int main(){
    49     int k;
    50     scanf("%d",&k);
    51     while(k--)    solve();
    52     return 0;
    53 }
    View Code

      然后第二个版本的,省去了dp数组,改用结点的结构体里增多一个变量来记录时间:

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<cstdlib>
     4 #include<queue>
     5 #include<algorithm>
     6 using namespace std;
     7 #define For(i,s,t)    for(int i=s; i<t; ++i)
     8 const int inf= 0x2fffffff;
     9 int a,b,c,T;
    10 int f[60][60][60];
    11 
    12 int dir[8][3]= {{0,0,1},{0,1,0},{-1,0,0},{1,0,0},{0,-1,0},{0,0,-1}};
    13 
    14 struct node{
    15     int x,y,z,t;
    16     node(int x=0, int y=0, int z=0, int t= inf): x(x),y(y),z(z),t(t) {}
    17     bool operator ==(const node &n2) const {
    18         return x==n2.x && y==n2.y && z==n2.z;
    19     }
    20 };
    21 
    22 void solve(){
    23     scanf("%d%d%d%d",&a,&b,&c,&T);
    24     For(i,0,a+2)    For(j,0,b+2)    For(k,0,c+2)
    25         f[i][j][k]= 1;
    26     For(i,1,a+1)    For(j,1,b+1)    For(k,1,c+1)
    27         scanf("%d",f[i][j]+k);
    28     
    29     //如果终点是墙就永远出不了,(这题挺坑的,起点不管是不是墙都不要紧) 
    30     //或者从起点到终点的最短直线距离比 T大的话也出不了,是个很重要的剪枝 
    31     if(f[a][b][c]==1 || a+b+c-3 > T)    {    puts("-1");     return ;    }
    32     
    33     node ed(a,b,c);
    34     queue<node> q;
    35     q.push(node(1,1,1,0));
    36     while(q.size()){
    37         node p= q.front();    q.pop();
    38         if(p == ed)        ed.t= min(ed.t,p.t);
    39         for(int k=0; k<6; ++k){
    40             int dx= p.x+dir[k][0], dy= p.y+dir[k][1], dz= p.z+dir[k][2];
    41             if(f[dx][dy][dz]!= 1){
    42                 q.push(node(dx,dy,dz,p.t+1));
    43                 f[dx][dy][dz]= 1;
    44             }
    45         }
    46     }
    47     //算出到达终点的时间后,还需判断是否满足题意
    48     if(ed.t > T)      puts("-1");
    49     else    printf("%d
    ",ed.t);
    50 }
    51 
    52 int main(){
    53     int k;
    54     scanf("%d",&k);
    55     while(k--)    solve();
    56     return 0;
    57 }
    View Code

      方向数组 dir[][][] 果然还是把 x,y,z 封装在一维里更好一些~~

  • 相关阅读:
    嘀嘀咕 (1)
    碎碎念(4)
    渲染层错误] TypeError: Cannot read property 'replace' of undefined at rewrit
    怎么跳出foreach
    vs code的Go Live不出现
    ES6
    h5分享到微信,分享到朋友圈
    网页之间传值与获取值
    原生js添加节点的高级简便写法
    原型链
  • 原文地址:https://www.cnblogs.com/Newdawn/p/4397944.html
Copyright © 2011-2022 走看看