1. 程式人生 > >百練 4116 拯救行動

百練 4116 拯救行動

總時間限制: 

1000ms

 

記憶體限制: 

65536kB

描述

公主被惡人抓走,被關押在牢房的某個地方。牢房用N*M (N, M <= 200)的矩陣來表示。矩陣中的每項可以代表道路(@)、牆壁(#)、和守衛(x)。 
英勇的騎士(r)決定孤身一人去拯救公主(a)。我們假設拯救成功的表示是“騎士到達了公主所在的位置”。由於在通往公主所在位置的道路中可能遇到守衛,騎士一旦遇到守衛,必須殺死守衛才能繼續前進。 
現假設騎士可以向上、下、左、右四個方向移動,每移動一個位置需要1個單位時間,殺死一個守衛需要花費額外的1個單位時間。同時假設騎士足夠強壯,有能力殺死所有的守衛。

給定牢房矩陣,公主、騎士和守衛在矩陣中的位置,請你計算拯救行動成功需要花費最短時間。

輸入

第一行為一個整數S,表示輸入的資料的組數(多組輸入)
隨後有S組資料,每組資料按如下格式輸入 
1、兩個整數代表N和M, (N, M <= 200). 
2、隨後N行,每行有M個字元。"@"代表道路,"a"代表公主,"r"代表騎士,"x"代表守衛, "#"代表牆壁。

輸出

如果拯救行動成功,輸出一個整數,表示行動的最短時間。
如果不可能成功,輸出"Impossible"

樣例輸入

2
7 8
#@#####@
#@a#@@[email protected]
#@@#[email protected]@@ @@#@@#@# #@@@##@@ @#@@@@@@ @@@@@@@@ 13 40 @[email protected]@##[email protected]#[email protected]#xxxx##@#[email protected]@@#x#@#x#@@[email protected]#@x xx###[email protected]#@@##[email protected]@@#@[email protected]@#[email protected]
@@#[email protected]#[email protected]@[email protected] #@x#@x#x#@@##@@x#@xx#[email protected]@x##@@@#@[email protected]@[email protected] @##[email protected]@@x#xx#@@#xxxx#@@[email protected]@#@[email protected]@@[email protected]#@#[email protected]# @#xxxxx##@@x##[email protected]@@#[email protected]####@@@x#x##@#@ #xxx#@#x##[email protected]@#[email protected]@@[email protected]#@#[email protected]##### #[email protected]#@[email protected]@@@##@x#xx#[email protected]#xx#@#####x#@x xx##@#@x##x##x#@x#@a#[email protected]##@#@##[email protected]#@@[email protected] x#x#@[email protected]#x#@##@[email protected]#[email protected]##x##xx#@#[email protected]@ #[email protected]@#@###x##[email protected]#@@#@@[email protected]@@[email protected]@@@##@@[email protected]@x x#[email protected]###@xxx#@#x#@@###@#@##@x#@[email protected]#@@#@@ #@#[email protected]#x#x###@[email protected]@xxx####[email protected]##@x####xx#@x #x#@x#x######@@#[email protected]#xxxx#[email protected]@@#xx#x#####@

樣例輸出

13
7

程式碼如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
struct Pos
{
    int x,y;
    int t;
    Pos(int a,int b,int c)
    {
        x = a;
        y = b;
        t = c;
    }
    Pos(){}
    bool operator < (const Pos &a) const
    {
        return t > a.t;
    }
};
Pos s,e,temp;
const int MAX = 220;
int M,N;
char Map[MAX][MAX];
int visited[MAX][MAX];
int l[MAX][MAX];
int dx[4] = {1,0,-1,0};
int dy[4] = {0,1,0,-1};
void BFS()
{
    priority_queue < Pos > q;
    q.push(s);
    while(!q.empty())
    {
        temp = q.top();
        q.pop();
        if((temp.x == e.x) && (temp.y == e.y))
        {
            printf("%d\n",temp.t);
            return;
        }
        for(int i = 0;i < 4; i++)
        {
            int tx = temp.x + dx[i];
            int ty = temp.y + dy[i];
            if(tx >= 0 && tx < N && ty >= 0 && ty < M && Map[tx][ty] != '#' && visited[tx][ty] == 0)
            {
                if(Map[tx][ty] == 'x')
                    q.push(Pos(tx,ty,temp.t + 2));
                else
                    q.push(Pos(tx,ty,temp.t + 1));
                visited[tx][ty] = 1;
            }
        }
    }
    printf("Impossible\n");
}
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d %d",&N,&M);
        memset(l,0,sizeof(l));
        memset(visited,0,sizeof(visited));
        for(int i = 0;i < N; i++)
        {
            getchar();
            for(int j = 0;j < M; j++)
            {
                scanf("%c",&Map[i][j]);
                if(Map[i][j] == 'x')
                    l[i][j] = 2;
                else
                    l[i][j] = 1;
                if(Map[i][j]=='r')
                    s = Pos(i,j,0);
				if(Map[i][j]=='a')
                    e = Pos(i,j,0);
            }
        }
        BFS();
    }
    return 0;
}