1. 程式人生 > >Nightmare 【HDU - 1072】【完整註釋+對於BFS初學者是絕對適用的】

Nightmare 【HDU - 1072】【完整註釋+對於BFS初學者是絕對適用的】

題目連結


  給個學弟看程式碼,看了半天,給他打了註釋,然後再將一些細節上改了下,還是挺累的,看程式碼吧,講解和註釋都附在上面了。


#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>
#include <limits>
#include <vector>
#include <stack>
#include <queue>
#include <set>
//#include <map>
#define lowbit(x) ( x&(-x) )
#define pi 3.141592653589793
#define e 2.718281828459045
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
struct MOGU
{
    int x, y, time, boom;      //(x,y),已經花費時間,爆炸時間
    MOGU(int a=0, int b=0, int c=0, int d=0):x(a), y(b), time(c), boom(d) {}    //這是初始化函式,有些編譯器需要
};
int map[10][10];
int book[10][10];
bool vis[10][10][8];    //(x, y),第三個元素是指這個點的狀態就是說距離爆炸時間的先後,要是之後有個更少的爆炸時間我們要更新我們的狀態
int xx[4]={-1, 1, 0, 0};
int yy[4]={0, 0, -1, 1};
int main ()
{
    int t, m, n, tx=0, ty=0, TIME, stx=0, sty=0;    //非全域性變數在定義的時候最好附上初始值
    scanf ("%d", &t);
    while (t--)
    {
        TIME=0;
        //memset(book,0,sizeof(book));
        memset(vis, false, sizeof(vis));    //布林型別的初始化
        scanf ("%d%d",&m,&n);
        for (int i=1;i<=m;i++)
            for (int j=1;j<=n;j++)
            {
                scanf ("%d", &map[i][j]);
                if (map[i][j] == 2)
                {
                    stx=tx=i;
                    sty=ty=j;
                    map[i][j] = 1;  //讓這個點成為可走點,為了之後的判斷方便
                }
            }
        queue<MOGU> q;
        MOGU head, tail;    //head是頭,tail是下一個可走路徑
        head.x = stx;
        head.y = sty;
        head.boom = 6;  //爆炸時間倒計時
        vis[stx][sty][6] = true;
        head.time = 0;  //初始時間為0
        q.push(head);
        while (!q.empty())
        {
            head=q.front();
            q.pop();
            if (head.boom==1)   //如果它就要爆炸,沒法走下去
            {
                //q.pop();    //下次得到優先佇列的隊頭元素後直接pop可以好記些。
                continue;
            }
            for (int i=0;i<=3;i++)
            {
                tx = head.x + xx[i];
                ty = head.y + yy[i];
                if ( tx<1 || ty<1 || tx>m || ty>n || map[tx][ty]==0 ) continue;  //你的book[i][j]遇到更優的解法沒辦法更新,所以可以用vis[i][j][boom]
                if (map[tx][ty] == 1)
                {
                    if(vis[tx][ty][head.boom-1]) continue;
                    tail.x = tx;
                    tail.y = ty;
                    tail.boom = head.boom - 1;
                    tail.time = head.time + 1;
                    q.push(tail);
                    vis[tx][ty][tail.boom] = true;
                }
                if (map[tx][ty]==3 && head.boom!=1)
                {
                    TIME = head.time+1;
                    break;
                }
                if (map[tx][ty] == 4)
                {
                    if(vis[tx][ty][6]) continue;
                    tail.x = tx;
                    tail.y = ty;
                    tail.boom = 6;
                    tail.time = head.time+1;
                    q.push(tail);
                    vis[tx][ty][6] = true;
                }
            }
            if (TIME) break;
        }
        if (TIME) printf ("%d\n",TIME);
        else printf ("-1\n");
    }
    return 0;
}