1. 程式人生 > >HDU 2531 Catch him(bfs整體處理)

HDU 2531 Catch him(bfs整體處理)

Catch him

Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1221    Accepted Submission(s): 550


 

Problem Description

在美式足球中,四分衛負責指揮整隻球隊的進攻戰術和跑位,以及給接球員傳球的任務。四分衛是一隻球隊進攻組最重要的球員,而且一般身體都相對比較弱小,所以通常球隊會安排5-7名大漢來保護他,其中站在四分衛前方、排成一線的5名球員稱為進攻鋒線,他們通常都是135公斤左右的壯漢。


對防守方來說,攻擊對手的四分衛當然是最直接的限制對手進攻的方法。如果效果好,就可以在對方四分衛傳球之前將其按翻在地,稱之為擒殺。擒殺是最好的鼓舞防守隊士氣的方法,因為對方連傳球的機會都沒有,進攻就結束了,還必須倒退一些距離開球。凶狠的擒殺甚至能夠將對方的四分衛弄傷,從而迫使對方更換這個進攻核心。
在本題中,輸入給出準備擒殺四分衛的防守球員的位置、對方每個進攻鋒線球員的位置以及對方四分衛的位置,你的任務是求出這名準備擒殺的防守球員至少要移動多少步,才能夠擒殺對方四分衛。
假設對方進攻鋒線和四分衛在這個過程中都不會移動。只有1名防守球員,防守球員只要碰到對方四分衛就算擒殺。
所有的球員都是一塊連續的、不中空的2維區域。防守球員不可以從進攻鋒線的身體上穿過,也不可以從界外穿過(只能走空地)。
防守隊員不可以轉動身體,只能平移。防守隊員的身體所有部分向同一個方向(上、下、左、右)移動1格的過程叫做1步。

 

 

Input

輸入包含多組資料。每組資料第一行都是兩個整數H,W(0<H,W<=100),表示整個區域的高度和寬度,H=W=0表示輸入結束。接下來有H行,每行W個字元。每個字元如果是’.’,表示這裡是空地,如果是’O’,表示是進攻鋒線隊員的身體,如果是’D’,表示是準備擒殺的防守球員的身體,如果是’Q’,表示是四分衛的身體。
輸入保證符合上面的條件。防守球員的身體總共不超過20格。

 

 

 

Output

對每組資料,輸出包含擒殺所需最少步數的一行。如果不能擒殺,輸出帶’Impossible’的一行。

 

 

Sample Input

 

6 6 .Q.... QQ..OO .OO..O ...O.O OO.O.. ....DD 7 7 .Q..... QQ.OOO. ...O... O...... OO..OO. .O..... .....DD 0 0

 

 

Sample Output

 

Impossible 9

 

 

Source

The 6th UESTC Programming Contest

 

 

Recommend

lcy   |   We have carefully selected several similar problems for you:  2544 3500 2821 1983 2822 

 注意是整體移動,並且不能碰到o

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
#define maxn 105
int dx[4]={1,-1,0,0};
int dy[4]={0,0,1,-1};

int h,w;
int vis[maxn][maxn];
int size;
char mp[maxn][maxn];
struct node
{
    int r[maxn];
    int c[maxn];
    int dis;
}start;
int bfs()
{
    queue<node>q;
    node u;

    memset(vis,0,sizeof(vis));
    q.push(start);
    vis[start.r[0]][start.c[0]]=1;
    while(!q.empty())
    {node u=q.front();
    q.pop();
        for(int d=0;d<4;d++)
        {node p=u;
            int i;
             p.dis=p.dis+1;
            for( i=0;i<size;i++)
            {
                p.r[i]+=dx[d];
               p.c[i]+=dy[d];
                if(p.r[i]<0||p.r[i]>=h||p.c[i]<0||p.c[i]>=w)
                  break;
                if(mp[p.r[i]][p.c[i]]=='O')
                    break;
            }
            if(i!=size)
            continue;
            if(vis[p.r[0]][p.c[0]])
                continue;

            for(int i=0;i<size;i++)
            {
                if(mp[p.r[i]][p.c[i]]=='Q')
                return p.dis;
            }
            vis[p.r[0]][p.c[0]]=1;
            q.push(p);


        }
    }
    return -1;
}
int main()
{
    while(~scanf("%d%d",&h,&w)&&h&&w)
    {size=0;
        for(int i=0;i<h;i++)
    scanf("%s",mp[i]);
    for(int i=0;i<h;i++)
        for(int j=0;j<w;j++)
        if(mp[i][j]=='D')
    {
        start.r[size]=i;
        start.c[size++]=j;
    }
    start.dis=0;
    int ans=bfs();
    if(ans==-1)
        printf("Impossible\n");
    else
        printf("%d\n",ans);
    }
    return 0;
}