1. 程式人生 > >HDU 4528 小明系列故事——捉迷藏

HDU 4528 小明系列故事——捉迷藏

題目連結:傳送門

Problem Description

  小明的媽媽生了三個孩子,老大叫大明, 老二叫二明, 老三..., 老三自然就叫小明瞭。   一天,小明的媽媽帶小明兄弟三人去公園玩耍,公園裡面樹木很多,有很多地方可以藏身, 於是他們決定玩捉迷藏。經過幾輪的猜拳後,第一輪是小明來找其他兩個人,遊戲規則很簡單:   只要小明可以在規定的時間內找到他們就算小明獲勝,並且被發現的兩個人猜拳決定誰在下一輪負責找人;如果在規定的時間內只找到一個人,那麼沒有被發現的人獲勝,被找到的人下一輪負責找人;如果在規定的時間內一個人都沒有找到,則小明失敗了,下一輪還是他來找人。現在小明想知道,在規定時間內,自己是否可以找到所有的人,現在他想請你來幫忙計算一下。   為了簡單起見,把公園看成是n行m列的矩陣,其中’S’表示小明,’D’表示大名,’E’表示二明,’X’表示障礙物,’.’表示通路。這裡,我們把發現定義為,可以直接看到對方, 也就是說兩個人在同一行或者同一列,並且中間沒有障礙物或者沒有其他人就可以看到對方。並且假設,大明,二明藏好以後就不會再改變位置,小明每個單位時間可以從當前的位置走到相鄰的四個位置之一,並且不會走出公園。

Input

測試資料第一行是一個正整數T,表示有T組測試資料。 每一組測試資料首先是三個正整數n,m,t,分別表示行數、列數和規定的時間,接下來n行,每行m個上述的字元,並且保證有且只有一個’S’,一個’E’,一個’D’。

[Technical Specification] T < 200 3 <= n, m <= 100 0 <= t <= 100

Output

每組先輸出一行Case c:(c表示當前的組數,從1開始計數); 接下來一行,如果小明可以在規定時間內找到所有的人,則輸出最少需要的時間,否則輸出-1。

Sample Input

3 5 6 3 XXD... ....E. ....X. ....S. ...... 5 6 3 XDX... ....E. ...... ....S. ...... 5 6 8 XXDX.. .XEX.. ...... ....S. ......

Sample Output

Case 1: -1 Case 2: 3 Case 3: -1

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
char m[105][105];
int n[105][105][3][3];
int dir[4][2] = {{-1,0},{0,1},{1,0},{0,-1}};
int w,s,tim;
int x1,y1;
struct nate
{
    int a,b,t,x,y;
};
void qur(nate &cur)
{
    int a,b,c,d;
    for(a=0;a<4;a++)
    {
        c=cur.x;
        d=cur.y;
        while(1)
        {
            c=c+dir[a][0];
            d=d+dir[a][1];
            if(c<0||c>=w||d<0||d>=s)
                break;
            if(m[c][d]=='D')
            {
                cur.a=1;
                break;
            }
            if(m[c][d]=='E')
            {
                cur.b=1;
                break;
            }
            if(m[c][d]=='X')
                break;
        }
    }
}
int bfs()
{
    nate next,rent;
    queue<nate>q;
    rent.x=x1;
    rent.y=y1;
    rent.a=0;
    rent.b=0;
    rent.t=0;
    q.push(rent);
    memset(n,0,sizeof(n));
    n[x1][y1][0][0]=1;
    int a,b,c,d;
    while(!q.empty())
    {
        rent=q.front();
        q.pop();
        qur(rent);
        if(rent.a==1&&rent.b==1)
            return rent.t;
        if(rent.t>=tim)
            continue;
        for(a=0;a<4;a++)
        {
            next.x=rent.x+dir[a][0];
            next.y=rent.y+dir[a][1];
            next.t=rent.t+1;
            next.a=rent.a;
            next.b=rent.b;
            if(next.x<0||next.x>=w||next.y<0||next.y>=s)
                continue;
            if(n[next.x][next.y][next.a][next.b])
                continue;
            if(m[next.x][next.y]!='.')
                continue;
            n[next.x][next.y][next.a][next.b]=1;
            q.push(next);
        }
    }
    return -1;
}
int main()
{
    int a,b,c,d,e,f;
    cin>>a;
    f=0;
    while(a--)
    {
        cin>>w>>s>>tim;
        for(b=0;b<w;b++)
        {
            for(c=0;c<s;c++)
            {
                cin>>m[b][c];
                if(m[b][c]=='S')
                {
                    x1=b;
                    y1=c;
                }
            }
        }
        e=bfs();
        printf("Case %d:\n",++f);
        cout<<e<<endl;
    }
    return 0;
}