【HDU1072】Nightmare,思路+解題報告+代碼

#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
#define INPUT
using namespace std;
const int c0de4fun = 10;
int x[4] = {1,-1,0,0};
int y[4] = {0,0,1,-1};
int maze[c0de4fun][c0de4fun];
/**
    Problem :HDOJ/HDU1072 - Nightmare
    Begin Time:Unknown
    End Time:Unknown
    Test Data:
    有一個146K的超級大測試文件,需要的可以PM我
    Output:用本程序對拼即可
    思路:
    廣度優先搜索+模擬,不用剪枝,不用記錄已訪問節點。記得把bombResetEquipment改成0或者改成1
    教訓:
    WA了幾次,教訓主要有兩點:
    1,看題要仔細,本題中bombResetEquipment只能用一次就消失了,我以爲能用很多次。
    2,在搜索中,自帶限制條件的,一般來說就不用mark已經訪問過的節點了
        所謂的限制條件,就是在一定步數之後可以讓節點消失(不被重複訪問)的條件
    本題中我的重大!!!錯誤!!!就在於,當訪問了bombResetEquipment之後就
    mark掉這個點,然後把visited清空,並記錄每個bombResetEquipment的位置,重新從這幾個位置開始搜索。
    但是這會導致一個問題,有些未擴展的狀態就被清空了。在146K的測試數據中可以看到這點
    這種情況可以是以下狀況:
    遇到了BRE,visited清空了,但是當前從BRE開始搜索,導致
    從開始'3'點通往出口的某個點得狀態變成了“已訪問”,並且從BRE開始搜索不能達到出口
    但是從開始點搜索是可以達到的,由於開始點通往出口的點被標註visited了,所以不能從這個點搜索了。
    導致不出正確結果。
*/
struct node
{
    int x;
    int y;
    int time;
    int depth;
};
queue<node> nodes;
void Solve(int startx,int starty,int N,int M)
{
    node tmp;
    bool isExisted = false;
    tmp.depth = 0;
    tmp.time = 6;
    tmp.x = startx;
    tmp.y = starty;
    nodes.push(tmp);
    while( !nodes.empty() )
    {
        tmp = nodes.front();nodes.pop();
        if( maze[tmp.x][tmp.y] == 4)
        {
            tmp.time = 6;
            maze[tmp.x][tmp.y] = 0;
            ///這裏還要mark一下
        }
        if( maze[tmp.x][tmp.y] == 3)
        {
            printf("%d\n",tmp.depth);isExisted = true;break;
        }
        for(int i = 0 ; i < 4; i++)
        {
            node tmp1 = tmp;
            tmp1.x = tmp.x + x[i];
            tmp1.y = tmp.y + y[i];
            tmp1.depth = tmp.depth + 1;
            tmp1.time = tmp.time - 1;
            if( tmp1.x < 1 || tmp1.x > N || tmp1.y < 1 || tmp1.y > M)
                continue; //數組越界
            if( tmp1.time <= 0 )
                continue;
            if ( maze[tmp1.x][tmp1.y] == 0 )
                continue;
            nodes.push(tmp1);
        }
    }
    if(!isExisted)
    {
        printf("-1\n");
    }
    while(!nodes.empty())
        nodes.pop();
}
int main()
{
    int T;
    int N,M;
    int startx,starty;
#ifdef INPUT
    freopen("b:\\acm\\hdu1072\\input.txt","r",stdin);
    //freopen("b:\\acm\\hdu1072\\output.txt","w",stdout);
#endif
    scanf("%d",&T);
    for(int t = 0 ; t < T; t++)
    {
        memset(maze,0,sizeof(int)*c0de4fun*c0de4fun);
        scanf("%d%d",&N,&M);
        for(int i = 1; i<=N; i++)
        {
            for(int j = 1; j<=M; j++)
            {
                scanf("%d",&maze[i][j]);
                if(maze[i][j] == 2)
                {
                    startx = i;
                    starty = j;
                }
            }
        }
        Solve(startx,starty,N,M);
    }
#ifdef INPUT
    fclose(stdin);
    //fclose(stdout);
#endif
    return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章