1. 程式人生 > >hdu1180-詭異的樓梯(bfs+優先佇列)

hdu1180-詭異的樓梯(bfs+優先佇列)

詭異的樓梯

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others)
Total Submission(s): 11689    Accepted Submission(s): 2895


Problem Description Hogwarts正式開學以後,Harry發現在Hogwarts裡,某些樓梯並不是靜止不動的,相反,他們每隔一分鐘就變動一次方向. 
比如下面的例子裡,一開始樓梯在豎直方向,一分鐘以後它移動到了水平方向,再過一分鐘它又回到了豎直方向.Harry發現對他來說很難找到能使得他最快到達目的地的路線,這時Ron(Harry最好的朋友)告訴Harry正好有一個魔法道具可以幫助他尋找這樣的路線,而那個魔法道具上的咒語,正是由你纂寫的. 

Input 測試資料有多組,每組的表述如下:
第一行有兩個數,M和N,接下來是一個M行N列的地圖,'*'表示障礙物,'.'表示走廊,'|'或者'-'表示一個樓梯,並且標明瞭它在一開始時所處的位置:'|'表示的樓梯在最開始是豎直方向,'-'表示的樓梯在一開始是水平方向.地圖中還有一個'S'是起點,'T'是目標,0<=M,N<=20,地圖中不會出現兩個相連的梯子.Harry每秒只能停留在'.'或'S'和'T'所標記的格子內.

Output 只有一行,包含一個數T,表示到達目標的最短時間. 
注意:Harry只能每次走到相鄰的格子而不能斜走,每移動一次恰好為一分鐘,並且Harry登上樓梯並經過樓梯到達對面的整個過程只需要一分鐘,Harry從來不在樓梯上停留.並且每次樓梯都恰好在Harry移動完畢以後才改變方向.

Sample Input 5 5 **..T **.*. ..|.. .*.*. S....
Sample Output 7 Hint
Hint 地圖如下:

分析:如何對樓梯的情況進行處理是關鍵,當我們碰到樓梯的時候,我們可以選擇等待,或直接走過去,且樓梯會動態變化。要對時間進行奇偶分類,來判斷樓梯的狀態,且對是否等待進行操作。利用優先佇列,使時間短的先走。還有一個非常關鍵的點,就是vis陣列的處理。詳見程式碼。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <string>
#include <queue>
#define INF 0x3f3f3f3f
#define Pn printf("\n")
#define CSH(a, b) memset(a, (b), sizeof(a))
#define ll long long
#define PRnode(q) priority_queue<node> q
using namespace std;
char s[25][25];
int dir[4][2]={-1,0, 1,0, 0,-1, 0,1};
int vis[25][25];
struct node
{
    int x;
    int y;
    int ti;
    bool operator < (const node &a) const
    {
        return ti>a.ti;//小值優先
    }
};
int main()
{
    int m,n;
    while(~scanf("%d%d",&n,&m))
    {
        node fr;
        int flag=0,ans=0;
        CSH(vis,-1);
        for(int i=0;i<n;i++)
        {
            getchar();
            for(int j=0;j<m;j++)
            {
                scanf("%c",&s[i][j]);
                if(s[i][j]=='S')
                {
                    fr.x=i;
                    fr.y=j;
                    fr.ti=0;
                    vis[i][j]=0;
                }
            }
        }
        PRnode(q);
        while(!q.empty())
        {
            q.pop();
        }
        q.push(fr);
        while(!q.empty())
        {
            node ne;
            ne=q.top();
            q.pop();
            for(int i=0;i<4;i++)
            {
                node no;
                no.x=ne.x+dir[i][0];
                no.y=ne.y+dir[i][1];
                no.ti=ne.ti;
                if(s[no.x][no.y]!='*'&&no.x>=0&&no.x<n&&no.y>=0&&no.y<m&&vis[no.x][no.y]<no.ti)
                {
                    if(s[no.x][no.y]=='|')
                    {
                        if(no.ti%2)
                        {
                            if(i==3&&s[no.x][no.y+1]!='*'&&no.y+1<m)
                            {
                                vis[no.x][no.y]=no.ti;
                                no.y+=1;
                                no.ti++;
                            }
                            else if(i==2&&s[no.x][no.y-1]!='*'&&no.y-1>=0)
                            {
                                vis[no.x][no.y]=no.ti;
                                no.y-=1;
                                no.ti++;
                            }
                            else
                            {
                                no.x-=dir[i][0];
                                no.y-=dir[i][1];
                                no.ti++;
                            }
                        }
                        else
                        {
                            if(i==1&&s[no.x+1][no.y]!='*'&&no.x+1<n)
                            {
                                vis[no.x][no.y]=no.ti;
                                no.x+=1;
                                no.ti++;
                            }
                            else if(i==0&&s[no.x-1][no.y]!='*'&&no.x-1>=0)
                            {
                                vis[no.x][no.y]=no.ti;
                                no.x-=1;
                                no.ti++;
                            }
                            else
                            {
                                no.x-=dir[i][0];
                                no.y-=dir[i][1];
                                no.ti++;
                            }
                        }
                        if(s[no.x][no.y]=='T')
                        {
                            no.ti++;
                            flag=2;
                            ans=no.ti;
                            break;
                        }
                    }
                    else if(s[no.x][no.y]=='-')
                    {
                        if(no.ti%2)
                        {
                            if(i==1&&s[no.x+1][no.y]!='*'&&no.x+1<n)
                            {
                                vis[no.x][no.y]=no.ti;
                                no.x+=1;
                                no.ti++;
                            }
                            else if(i==0&&s[no.x-1][no.y]!='*'&&no.x-1>=0)
                            {
                                vis[no.x][no.y]=no.ti;
                                no.x-=1;
                                no.ti++;
                            }
                            else
                            {
                                no.x-=dir[i][0];
                                no.y-=dir[i][1];
                                no.ti++;
                            }
                        }
                        else
                        {
                            if(i==3&&s[no.x][no.y+1]!='*'&&no.y+1<m)
                            {
                                vis[no.x][no.y]=no.ti;
                                no.y+=1;
                                no.ti++;
                            }
                            else if(i==2&&s[no.x][no.y-1]!='*'&&no.y-1>=0)
                            {
                                vis[no.x][no.y]=no.ti;
                                no.y-=1;
                                no.ti++;
                            }
                            else
                            {
                                no.x-=dir[i][0];
                                no.y-=dir[i][1];
                                no.ti++;
                            }
                        }
                        if(s[no.x][no.y]=='T')
                        {
                            no.ti++;
                            flag=2;
                            ans=no.ti;
                            break;
                        }
                    }
                    else if(s[no.x][no.y]=='.')
                    {
                        no.ti++;
                    }
                    else if(s[no.x][no.y]=='T')
                    {
                        no.ti++;
                        flag=1;
                        ans=no.ti;
                        break;
                    }
                    if(s[no.x][no.y]=='.')
                    {
                        vis[no.x][no.y]=no.ti;
                    }
                    q.push(no);
                }
            }
            if(flag)
            {
                break;
            }
        }
        flag==1?printf("%d\n",ans):printf("%d\n",ans-1);
    }
}