1. 程式人生 > >HDU1180——詭異的樓梯(BFS+優先佇列)

HDU1180——詭異的樓梯(BFS+優先佇列)

詭異的樓梯

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


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 地圖如下:
這是一道不是很難的搜尋題,但是做的過程卻十分坎坷。
剛開始的時候沒有想到是用優先佇列,所以答案總是不對。
後來發現了這個問題之後,寫了個優先佇列,發現還是不對,主要問題還是出在梯子上。
而且剛開始沒有看到題目中的說明:不可能存在兩個相連的梯子。這個也困擾了我好久,最後發現根本沒有必要。


對於梯子的處理我是這樣做的(以‘ - ’梯子為例):
if(map[v.y][v.x]=='-')
                {
                    if(a[i][1]==0&&v.t%2==1||a[i][0]==0&&v.t%2==0)
                        v.x+=a[i][0],v.y+=a[i][1];
                    else v.x+=a[i][0],v.y+=a[i][1],v.t++;
                    if(map[v.y][v.x]=='T') return v.t;
}
首先是要確定方向,就是你移動方向要與梯子方向一致,其中a[i][1]==0表示Y軸位移為零,然後v.t%2==1時間 為奇數表示當前梯子為原始狀態。
如果可以通過梯子就按照原來方向再走一步,否則就在原地等一秒再通過,即t++;
由於梯子後面可能是終點,所以要加上一個判斷。
其實在後面還有判斷,判斷該點是否為‘*’,如果是就不加入佇列。
#include<stdio.h>
#include<string.h>
struct s
{
    int x,y,t;
}q[100001],u,v;
char map[22][22];
int sx,sy;
int end=1;
void ins(struct s e)
{
    int i;
    i=end;
    for(;end!=1&&q[i/2].t>=e.t;)
    {
        q[i]=q[i/2];
        i/=2;
    }
    q[i]=e;
    end++;
}
void keep(int i,int n)
{
    struct s temp;
    int child;
    temp=q[i];
    for(;i*2<n;i=child)
    {
        child=i*2;
        if(child+1!=n&&q[child].t>q[child+1].t)
            child++;
        if(q[child].t<temp.t)
            q[i]=q[child];
        else break;
    }
    q[i]=temp;

}
struct s out()
{
    struct s t;
    end--;
    t=q[1],q[1]=q[end],q[end]=t;
    keep(1,end);
    return q[end];
}

int bfs()
{
    int a[4][2]={1,0,0,1,-1,0,0,-1};
    int i;
    u.x=sx,u.y=sy,u.t=0;
    ins(u);
    while(end>1)
    {
        u=out();
        for(i=0;i<4;i++)
        {
            v=u;
            v.x+=a[i][0];
            v.y+=a[i][1];
            if(map[v.y][v.x]!='*')
            {
                v.t++;
                if(map[v.y][v.x]=='T')
                {
                    return v.t;
                }
                else if(map[v.y][v.x]=='-')
                {
                    if(a[i][1]==0&&v.t%2==1||a[i][0]==0&&v.t%2==0)
                        v.x+=a[i][0],v.y+=a[i][1];
                    else v.x+=a[i][0],v.y+=a[i][1],v.t++;
                    if(map[v.y][v.x]=='T') return v.t;

                }
                else if(map[v.y][v.x]=='|')
                {
                    if(a[i][0]==0&&v.t%2==1||a[i][1]==0&&v.t%2==0)
                        v.x+=a[i][0],v.y+=a[i][1];
                    else v.x+=a[i][0],v.y+=a[i][1],v.t++;
                    if(map[v.y][v.x]=='T') return v.t;
                }
                if(map[v.y][v.x]!='*')
                {
                    map[v.y][v.x]='*';
                    ins(v);
                }

            }
        }
    }

}
int main()
{
    int m,n,i,j;
    //freopen("in.txt","r",stdin);
    while(scanf("%d%d",&m,&n)!=EOF)
    {
        end=1;
        memset(map,'*',sizeof(map));
        getchar();
        for(i=1;i<=m;i++)
        {
            for(j=1;j<=n;j++)
            {
                scanf("%c",&map[i][j]);
                if(map[i][j]=='S') sx=j,sy=i;
            }
            getchar();
        }

        printf("%d\n",bfs());
    }
    return 0;
}


相關推薦

HDU1180——詭異樓梯BFS+優先佇列)

詭異的樓梯 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others) Total Submission(s): 7813    Accepted Submis

hdu1180 詭異樓梯BFS+優先佇列

詭異的樓梯 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others) Total Submission(s): 10827    Accepted Submi

hdu 1180 詭異樓梯bfs+優先佇列

詭異的電梯,實在詭異!!! 分析到詭異的地方時,把我都搞迷了! 看你別人的程式碼!才知道這樣分析!!! 這題關鍵判斷電梯的方向!!!人可以為了減少時間停在原地不動等電梯改變方向!!! #include<stdio.h> #include<string.h

杭電1180——詭異樓梯BFS+優先佇列

主要演算法:遇到樓梯時,如果樓梯方向和前進方向一致且通過樓梯的下一格能走,則前進且時間加一。如果樓梯方向和前進方向不一致,則在原地等一分鐘。 至於樓梯方向的判斷,無需每時每刻都改變一下樓梯的方向,只需根據當前時間,如果時間為偶數,則樓梯方向與初始方向一樣,如

Codeforces 134C Swaps bfs+優先佇列)【模板】

There are n players sitting at a round table. All of them have s cards of n colors in total. Besides, initially the first person had ca

hdu 2822BFS+優先佇列

Prairie dog comes again! Someday one little prairie dog Tim wants to visit one of his friends on the farmland, but he is as lazy as his friend (who require

HDU 1242Rescuebfs+優先佇列

Rescue Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 65536/32768K (Java/Other) Total Submission(s) : 4   Accepted Submission(

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

詭異的樓梯 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others) Total Submission(s): 11689    Accepted Submis

HDU 1180 詭異樓梯(BFS+優先佇列)

詭異的樓梯 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others) Total Submission(s): 13186    Accepted Submis

HDU1180 詭異樓梯 廣搜 優先佇列

7 HintHint 地圖如下: #include<iostream> #include<cstdio> #include<cstring> #include<queue> #define qq 22 using namespace std; char ma

【搜尋之BFS + 優先佇列】杭電 hdu 1180 詭異樓梯

/* THE PROGRAM IS MADE BY PYY */ /*----------------------------------------------------------------------------// Copyright (c) 2012

Rescue 3解法:1.DFS 2. BFS 3.BFS+優先佇列模板)

Angel was caught by the MOLIGPY! He was put in prison by Moligpy. The prison is described as a N * M (N, M <= 200) matrix. There are W

【51Nod - 1163】最高的獎勵 貪心+優先佇列 或 妙用並查集)

題幹: 有N個任務,每個任務有一個最晚結束時間以及一個對應的獎勵。在結束時間之前完成該任務,就可以獲得對應的獎勵。完成每一個任務所需的時間都是1個單位時間。有時候完成所有任務是不可能的,因為時間上可能會有衝突,這需要你來取捨。求能夠獲得的最高獎勵。 Input 第1行:一個數N,表示

HDU1242 Rescue BFS+優先佇列

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

L. Magical Girl Haze 分層最短路、bfs + 優先佇列+、最短路

L-Magical Girl Haze Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 256MB Problem Description There are N cities in the country, and M direc

【Codeforces-140C】New Year Snowmen貪心+優先佇列、二分)

As meticulous Gerald sets the table and caring Alexander sends the postcards, Sergey makes snowmen. Each showman should consist of three snowballs:

CCF-CSP201609-4 交通規劃Dijkstra+優先佇列

題目連結 問題描述 試題編號: 201609-4 試題名稱: 交通規劃 時間限制: 1.0s 記憶體限制: 256.0MB 問題描述: 問題描述   G國國王來中國參觀後,被中國的高速鐵路深深的震撼,決定為自己

最短路Dijkstra + 優先佇列優化)

#include <iostream> #include <cstdio> #include <queue> #include <vector> using namespace std; const int Ni = 20001

HDU 6438 Buy and Resell貪心+優先佇列+set)

Description 有nnn個城市,第iii個城市商品價格為aia_iai​,從111城市出發依次經過這nnn個城市到達nnn城市,在每個城市可以把手頭商品出售也可以至多買一個商品,問最大收益以及在

hdu1026 bfs+優先佇列+記錄方向

這篇文章讓我收穫相當大。。。做了4個小時,最後還是跑去看了別人的題解 1:思路:bfs+優先佇列 用flag[x][y]記錄走到(x,y)處,上一步走的方向(用0,1,2,3表示),flag[][]陣列初始化都是-1。因為標記了flag陣列,加上個判斷,王子就不會走已經走