救公主(BFS)

Problem D: 救公主續

Time Limit: 1 Sec  Memory Limit: 128 MB
Submit: 48  Solved: 19
[Submit][Status][Web Board]

Description

公主又被魔王抓去了!公主被關在一個矩形迷宮裏,有的位置有守衛把守。年邁的國王正是心急如焚,告招天下勇士來拯救公主。不過公主早已習以爲常,她深信智勇的騎士肯定又會將她救出。初始時騎士在迷宮左上角(0,0)處,公主在右下角(n-1,m-1),騎士可向上下左右四個方向走,每走一步需要一個單位時間,如果該位置有守衛,需要消耗一定的時間來對付,問騎士最快需要多少時間到達公主。

Input

輸入有多組,每組第一行兩個不超過100的整數n,m,表示矩形的長和寬,接下的n行m列代表迷宮,'X'代表障礙物,'.'代表道路,數字則表示該位置有守衛,對付該守衛需要的時間爲這個數值

Output

輸出騎士到公主位置的最小時間,格式見樣例,若不能到達輸出“God please help our poor hero.”

Sample Input

5 6
.XX.1.
..X.2.
2...X.
...XX.
XXXXX.
5 6
.XX...
..XX1.
2...X.
...XX.
XXXXX.

Sample Output

It takes 13 seconds to reach the target position.
God please help our poor hero.

HINT


該題和一般的bfs不一樣,因爲該題不是每走一步時間就加一,如果碰到小兵,就會額外的增加時間,這樣就導致從不同方向到達同一點的時間有所不同,該題是想求出最少的時間,所以如果遇到多次遍歷到同一點的時候,我們應該將他們此時所花費的時間進行比較,取花費時間少的那個節點放入隊列中,後面就從該節點進行遍歷,每一步都進行這樣的操作。最後就能得到最少的時間了,例如,我們可以用一個數組vis[100][100]來保存到達每個點的時間,我們可以先將該數組的每個數初始化一個很大的數,然後將每個節點的時間與該座標的標記的時間進行比較,如果小於,則放入隊列中。(如果第一次遍歷到該點,進行比較後就直接放入隊列,如果第二次或者多次遍歷到該店,就將此時的時間與前一次在該點標記的時間進行比較,如果比它小,說明該條路線花費的時間較少,此時我們就將它放入隊列,此後就可以從該點進行後面的操作)。


具體實現代碼:

#include<stdio.h>
#include<iostream>
#include<queue>
using namespace std;
int N,M;
char map[100][100];
int result;
int vis[100][100];//記錄走到該位置所花時間 
int dir[4][2]={{-1,0},{0,-1},{1,0},{0,1}};
struct node{
       int x;
  int y;
       int time;
};
bool check(int x,int y)//檢查是否出界

    if(x>=0&&y>=0&&x<N&&y<M)
return true;
    return false;
}
int DFS(int x,int y){
    struct node start,next;
    queue<node>Q;
    start.x=x;
    start.y=y;
    start.time=0;
    vis[0][0]=0;//標記 
    Q.push(start);
    while(!Q.empty())
{
        start=Q.front();
Q.pop();
        if(start.x==N-1&&start.y==M-1)
{
  result=start.time;
        }
        for(int i=0;i<4;i++){
                int dx=start.x+dir[i][0];
                int dy=start.y+dir[i][1];
                if(check(dx,dy)&&map[dx][dy]=='.')
{
                    next.x=dx;
                    next.y=dy;
                    next.time=start.time+1;
                    if(next.time<vis[next.x][next.y]){
                        vis[next.x][next.y]=next.time;
                       // mark[next.x][next.y]=1;
                        Q.push(next);
                    }
                }
                else if(check(dx,dy)&&(map[dx][dy]>='1'&& map[dx][dy]<='9'))
{
                     next.x=dx;
                     next.y=dy;
                     next.time=start.time+1+map[dx][dy]-'0';
                    if(next.time<vis[next.x][next.y]){
                        vis[next.x][next.y]=next.time;
                        Q.push(next);
                    }
                }
        }
    }
    return result;
}
int main(){
    int i,j;
    while(cin>>N>>M)
{
        for(i=0;i<100;i++)
        for(j=0;j<100;j++)
        vis[i][j]=10000;
        for(i=0;i<N;i++)
        cin>>map[i];
        result=10000;
        int t=DFS(0,0);
        if(t==10000)
        cout<<"God please help our poor hero."<<endl;
        else
        cout<<"It takes "<<t<<" seconds to reach the target position."<<endl;
    }
    return 0;
}


發佈了33 篇原創文章 · 獲贊 4 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章