題目523:亡命逃竄

題目鏈接:

http://acm.nyist.net/JudgeOnline/problem.php?pid=523

描述

從前有個叫hck的騎士,爲了救我們美麗的公主,潛入魔王的老巢,夠英雄吧。不過英雄不是這麼好當的。這個可憐的娃被魔王抓住了,倍受折磨,生死一線。有一天魔王出去約會了,這可是一個千載難逢的逃命機會。你現在的任務就是判斷一下這個英雄未遂的孩子能不能在魔王回來之前逃出魔王的城堡,成功逃生,最後迎娶我們美麗的公主。

魔王住在一個城堡裏,城堡是一個A*B*C的立方體,可以被表示成A個B*C的矩陣,剛開始hck被關在(0,0,0)的位置,離開城堡的門在(A-1,B-1,C-1)的位置,現在知道魔王將在T分鐘後回到城堡,hck每分鐘能從一個座標走到相鄰的六個座標中的其中一個.現在給你城堡的地圖,請你計算出hck能否在魔王回來前離開城堡(只要走到出口就算離開城堡,如果走到出口的時候魔王剛好回來也算逃亡成功),如果可以請輸出需要多少分鐘才能離開,如果不能則輸出-1.
這裏寫圖片描述
如圖所示,輸入數據中的第0塊的最左上角是hck被關的地方,第A-1塊的最右下角是城堡的出口。按照圖中紅色箭頭方向移動每一層以構成整個城堡。

輸入

輸入數據的第一行是一個正整數K,表明測試數據的數量. 每組測試數據的第一行是四個正整數A,B,C和T(1≤,C≤50,1≤T≤1000),它們分別代表城堡的大小和魔王回來的時間.
然後是A塊輸入數據(先是第0塊,然後是第1塊,第2塊……),每塊輸入數據有B行,每行有C個正整數,代表迷宮的佈局,其中0代表路,1代表牆.
(如果對輸入描述不清楚,可以參考上面的迷宮描述,它表示的就是上圖中的迷宮)

輸出

對於每組測試數據,如果hck能夠在魔王回來前離開城堡,那麼請輸出他最少需要多少分鐘,否則輸出-1.

樣例輸入

2
3 2 2 10
0 1
0 0
1 1
1 0
0 0
0 1
3 3 4 20
0 1 1 1
0 0 1 1
0 1 1 1
1 1 1 1
1 0 0 1
0 1 1 1
0 0 0 0
0 1 1 0
0 1 1 0

樣例輸出

-1
11

算法思想:

求一個狀態到另一個狀態使用廣度優先算法。只不過是二維的一個擴展,輸入規模很大,剛開始寫的時候使用cin、cout超時,以爲算法的問題,後來將之改爲scanf和printf即可。
廣度優先是從一個始點開始搜索,將其相鄰的點進隊列,然後搜索隊列以此類推即可,退出條件是搜索的路徑長度大於已給定的路徑長度或者搜索的到了終點,或者所有點均已遍歷完。

源代碼

/*
Author:YangLinfeng
Date:2017.10.09
NYOJ(523):BFS
*/
#include <iostream>
#include <queue>
#include <cstring>
#include <cstdio>
using namespace std;
int map[55][55][55], visited[55][55][55], A, B, C, T;
struct Node{
    int x, y, z, steps;
};
queue<Node> Q;
Node pre,curr;
//六個方向
int dir[6][3] = { { 1, 0, 0 }, { -1, 0, 0 }, { 0, 1, 0 }, { 0, -1, 0 }, { 0, 0, 1 }, { 0, 0, -1 } };
//廣度搜索
int bfs(Node start)
{
    while (!Q.empty()) Q.pop();
    Q.push(start);
    int x, y, z;
    while (!Q.empty())
    {
        pre = Q.front();
        Q.pop();
        visited[pre.x][pre.y][pre.z] = 1;
        for (int i = 0; i < 6; i++)
        {
            x = pre.x + dir[i][0], y = pre.y + dir[i][1], z = pre.z + dir[i][2];
            if (x >= 0 && x < A && y >= 0 && y < B && z >= 0 && z < C && !map[x][y][z] && !visited[x][y][z])
            {
                curr = { x, y, z, pre.steps + 1 };
                if (curr.steps > T)
                    return -1;
                if (x == A - 1 && y == B - 1 && z == C - 1)
                    return curr.steps;
                visited[x][y][z] = 1;
                Q.push(curr);
            }
        }
    }
    return -1;
}
int main()
{
    int K;
    cin >> K;
    while (K--)
    {
        cin >> A >> B >> C >> T;
        memset(map, 0, sizeof(map)), memset(visited, 0, sizeof(visited));
        for (int i = 0; i < A; i++)
        {
            for (int j = 0; j < B; j++)
            {
                for (int k = 0; k < C; k++)
                {
                    scanf("%d", &map[i][j][k]);
                }
            }
        }
        Node start = { 0, 0, 0, 0 };
        int ans = bfs(start);
        if (ans <= T)
            printf("%d\n", ans);
        else
            printf("-1\n");
    }
    return 0;
}

最優源代碼


#include<stdio.h>
#include<string.h>
#include<queue>
using namespace std;
int kj[]={0,0,0,0,1,-1},sx[]={0,0,1,-1,0,0},zy[]={1,-1,0,0,0,0};
int map[60][60][60],ac[60][60][60];
int n,m,w,t;
struct hello
{
    int x,y,z,step;
};
void bfs()
{
    int a,b,x,y,z,sum,loop=0;
    queue<hello>Q;
    hello ok1={1,1,1,0};
    Q.push(ok1);
    ac[1][1][1]=1;
    while(!Q.empty())
    {
        x=Q.front().x;
        y=Q.front().y;
        z=Q.front().z;
        sum=Q.front().step;
        Q.pop();
        if(x==w&&y==n&&z==m)
            {loop=1;break;}
        for(a=0;a<6;a++)
        {
            int i=x+kj[a];
            int j=y+sx[a];
            int p=z+zy[a];
            if(ac[i][j][p]==0&&map[i][j][p]==1)
            {
                hello ok2={i,j,p,sum+1};
                Q.push(ok2);
                ac[i][j][p]=1;
            }
        }


    }
    if(sum<=t&&loop==1)
       printf("%d\n",sum);
    else
       printf("-1\n");


}
int main()
{
    int a,b,c,k,kkk;
    scanf("%d",&k);
    while(k--)
    {
        memset(ac,0,sizeof(ac));
        memset(map,0,sizeof(map));
        scanf("%d %d %d %d",&w,&n,&m,&t);
        for(c=1;c<=w;c++)
          for(a=1;a<=n;a++)
            for(b=1;b<=m;b++)
                 {
                     scanf("%d",&kkk);
                     if(kkk==0)
                        map[c][a][b]=1;
                     else
                        map[c][a][b]=0;
                 }
       if(map[w][n][m]==0||w+n+m>t)
         {printf("-1\n");continue;}
        bfs();
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章