1. 程式人生 > >洛谷P1189'SEARCH'

洛谷P1189'SEARCH'

題目描述

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

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

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

小鎮的地圖是矩形的,上面的符號用來標明哪兒可以行車哪兒不行。“.”表示小鎮上那塊地方是可以行車的,而符號“X”表示此處不能行車。

拉爾夫所開小車的初始位置用字元的“*”表示,且汽車能從初始位置通過。

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

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

輸入輸出格式

輸入格式:

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

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

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

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

輸出格式:

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

輸入輸出樣例:

輸入:
4 5

. . . . .

. x . . .

. . . * x

x . x . .

3

NORTH

WEST

SOUTH

輸出:
. . . . .

* x * . .

* . * . x

x . x . .

思路:

題目描述的很清楚了,我就簡單的在說一遍吧,由題意得我們需要在圖中遍歷找出能停車的所有點但是能停車的點是有要求的,

當輸入時我們會給出N個不同的方向,我們在圖中遍歷時必須滿足行走完這N個不同的方向才能停車且用“*”表示.

很直接的我們第一時間會想到搜尋BFS或者DFS(因為我比較喜歡BFS於是這篇題解就是用BFS實現的).

 

但是這題的移動方向是未明確的,我的意思是我們必須在輸入中才能明確我們的移動方向,因此我們將會進行多次BFS但是我們知道每當進行一次BFS,

我們的佇列就會彈空,因此當我們進行下一個方向的遍歷時就無法用上一個狀態更新所以這題的核心到了我們需要兩個佇列que和keay

que即我們BFS所需要的佇列,keay就是每當我們跑完一邊BFS就將當前的所有更新的值存進去當個暫存器,進行下一次再取出來更新就完成了本題更新操作

程式碼:

void update()//update就是我們進行儲存的操作 
{
    while(!keay.empty())
    {
        que.push(keay.front());//push回que佇列 
        keay.pop();
    }
}

 

這題重要的核心思想完成了

接下來我們講此題可能出現的情況.

由題意我們可以得知我們需要將能停車的地方更新為字元"*"

但是如果這個點我們在之前就已經更新過那我們以後的更新就是重複的這個地方我們就可以剪枝否則很有可能會超時

程式碼:

if(vis[now.x][now.y][t]) 
        continue;
        vis[now.x][now.y][t]=true;

完整程式碼:

#include <iostream>
#include <cstring>
#include <string>
#include <queue>
using namespace std;
const int N=60;
char Map[N][N];
bool vis[N][N][1000+100];
int n,m,op,flag,startx,starty;
struct Node//結構體不解釋 
{
    int x,y;
};
queue<struct Node> keay;//此題核心:queue<struct Node>keay這個佇列可以看作為中轉站將que這個佇列每次更新的數值儲存起來 
queue<struct Node> que;//再由keay佇列push回que再次更新從而達到遍歷全圖的目的 
void update()//update就是我們進行儲存的操作 
{
    while(!keay.empty())
    {
        que.push(keay.front());//push回que佇列 
        keay.pop();
    }
}
void bfs(int dir,int t)//bfs進行遍歷 
{
    struct Node now;
    if(flag==0)//這個地方可以寫在主函式(我這樣寫麻煩了些)flag 
    {          //為了防止每次從keay佇列彈回que佇列時多加入初始點所以我們用flag標記一下 
        now.x=startx;now.y=starty;
        que.push(now);
        flag++;
    }
    while(!que.empty())
    {
        now=que.front();
        que.pop();
        if(vis[now.x][now.y][t]) 
        continue;
        vis[now.x][now.y][t]=true;
        for(int i=1;;i++)
        {
            if(dir==1)
            {
                int xx=now.x-i;
                int yy=now.y;
                if(xx<1) break;
                if(Map[xx][yy]=='X') break;
                if(t==op)
                Map[xx][yy]='*';
                struct Node next;
                next.x=xx;next.y=yy;
                keay.push(next);
            }
            if(dir==2) 
            {
                int xx=now.x;
                int yy=now.y-i;
                if(yy<1) break;
                if(Map[xx][yy]=='X') break;
                if(t==op) 
                Map[xx][yy]='*';
                struct Node next;
                next.x=xx;next.y=yy;
                keay.push(next);
            }
            if(dir==3)//...........
            {
                int xx=now.x;
                int yy=now.y+i;
                if(yy>m) break;
                if(Map[xx][yy]=='X') break;
                if(t==op)
                Map[xx][yy]='*';
                struct Node next;
                next.x=xx;next.y=yy;
                keay.push(next);
            }
            if(dir==4)//...........
            {
                int xx=now.x+i;
                int yy=now.y;
                if(xx>n) break;
                if(Map[xx][yy]=='X') break;
                if(t==op)
                Map[xx][yy]='*';
                struct Node next;
                next.x=xx;next.y=yy;
                keay.push(next);
            }
        }
    }
    return;
}
int main()
{
    cin>>n>>m;
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            cin>>Map[i][j];
            if(Map[i][j]=='*')
            {
                startx=i;
                starty=j;
                Map[i][j]='.';
            }
        }
    }
    cin>>op;//操作方向個數 
    for(int i=1;i<=op;i++) 
    {
        string s;
        int direct;
        cin>>s;
        if(s=="NORTH") direct=1;
        if(s=="WEST") direct=2;
        if(s=="EAST") direct=3;
        if(s=="SOUTH") direct=4;
        bfs(direct,i);
        if(i<op)
        update();
    }
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            cout<<Map[i][j];
        }
        cout<<endl;
    }
    return 0;
}