天天看點

wikioi-天梯-普及一等-bfs-1026:逃跑的拉爾夫

題目描述 Description

年輕的拉爾夫開玩笑地從一個小鎮上偷走了一輛車,但他沒想到的是那輛車屬于警察局,并且車上裝有用于發射車子移動路線的裝置。

那個裝置太舊了,以至于隻能發射關于那輛車的移動路線的方向資訊。

編寫程式,通過使用一張小鎮的地圖幫助警察局找到那輛車。程式必須能表示出該車最終所有可能的位置。

小鎮的地圖是矩形的,上面的符号用來标明哪兒可以行車哪兒不行。“.”表示小鎮上那塊地方是可以行車的,而符号“X”表示此處不能行車。拉爾夫所開小車的初始位置用字元的“*”表示,且汽車能從初始位置通過。

汽車能向四個方向移動:向北(向上),向南(向下),向西(向左),向東(向右)。

拉爾夫所開小車的行動路線是通過一組給定的方向來描述的。在每個給定的方向,拉爾夫駕駛小車通過小鎮上一個或更多的可行車地點。

輸入描述 Input Description

輸入檔案的第一行包含兩個用空格隔開的自然數R和C,1≤R≤50,1≤C≤50,分别表示小鎮地圖中的行數和列數。

以下的R行中每行都包含一組C個符号(“.”或“X”或“*”)用來描述地圖上相應的部位。

接下來的第R+2行包含一個自然數N,1≤N≤1000,表示一組方向的長度。

接下來的N行幅行包含下述單詞中的任一個:NORTH(北)、SOUTH(南)、WEST(西)和EAST(東),表示汽車移動的方向,任何兩個連續的方向都不相同。

輸出描述 Output Description

輸出檔案應包含用R行表示的小鎮的地圖(象輸入檔案中一樣),字元“*”應該僅用來表示汽車最終可能出現的位置。

樣例輸入 Sample Input

4 5

.....

.X...

...*X

X.X..

3

NORTH

WEST

SOUTH

樣例輸出 Sample Output

.....

*X*..

*.*.X

X.X..

類型:圖論  難度:2

題意:給一張r*c的圖,'.'為可走,'*'為初始位置,'X'為不可走。給出每步走的方向,将最終可能出現的位置标記為'*'并輸出。

分析:bfs題目。用隊列記錄走每一步可能出現位置,最終更新圖輸出即可,注意去重,我用的是set,但是用stl一般比較慢,後來想了一下,可以用數組做隊列(二進制組存儲位置(i,j)),用一個每次重新整理的臨時圖(二維數組)記錄這一步可能出現的位置,用來去重,應該會達到更快的速度。

代碼:

#include<iostream>
#include<cstring>
#include<string>
#include<map>
#include<set>
#include<cstdio>
using namespace std;

string m[60];
int r,c,n;
set<pair<int,int> > now;
int dir[4][2] = {{-1,0},{1,0},{0,-1},{0,1}};

int main()
{
    now.clear();
    cin>>r>>c;
    for(int i=0; i<r; i++)
        cin>>m[i];
    for(int i=0; i<r; i++)
        for(int j=0; j<c; j++)
            if(m[i][j] == '*')
            {
                now.insert(make_pair(i,j));
                m[i][j] = '.';
                break;
            }
    
    cin>>n;
    for(int i=0; i<n; i++)
    {
        string tmp;
        cin>>tmp;
        int d;
        if(tmp=="NORTH") d = 0;
        else if(tmp=="SOUTH") d = 1;
        else if(tmp=="WEST") d = 2;
        else d = 3;
        
        set<pair<int,int> > pre(now);
        now.clear();
        for(set<pair<int,int> >::iterator it = pre.begin(); it!=pre.end(); it++)
        {
            int x = it->first;
            int y = it->second;
            for(int nx=x+dir[d][0],ny=y+dir[d][1]; ; nx+=dir[d][0],ny+=dir[d][1])
            {
                if(nx<0||nx>=r||ny<0||ny>=c||m[nx][ny]=='X')
                    break;
                now.insert(make_pair(nx,ny));
            }
        }        
    }
    for(set<pair<int,int> >::iterator it = now.begin(); it!=now.end(); it++)
    {
        int x = it->first;
        int y = it->second;
        
        m[x][y] = '*';
    }
    
    for(int i=0; i<r; i++)
        cout<<m[i]<<endl;
    
}