提升coding能力------搜索專題(8)-----poj 1475

pku 1475 Pushing Boxes
題目地址:
http://acm.pku.edu.cn/JudgeOnline/problem?id=1475

題目大意:

模擬推箱子,給你一個矩陣,矩陣中有些是牆,再給你箱子,目標點和人的座標(二者的初始位置不一定相鄰),問是否存在一個路徑使得人可以把箱子推到終點,如果存在,輸出最短路徑,要是最短路徑有多條,可以輸出任意一條。

具體分析:

這題比較妙,首先我們要用到雙BFS,也就是BFS中嵌套BFS,我們首先要在(箱子到終點的BFS)這個過程中,每當箱子進行一個合法的移動,我們就可以根據箱子移動後的末位置來反推出人應該在箱子的哪個方向以及具體座標,然後進行(人到對應的推箱位置的BFS),當然在此過程中應該記錄路徑。

以後會詳細分析。

AC代碼:

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<queue>
using namespace std;
#define N 22
//
int r, c;
char Map[N][N];
bool vis2[N][N];
bool vis1[N][N];
int dirc[4][2] = { {1,0}, {-1,0}, {0,1}, {0,-1} };
char name_walk[4]={'s','n','e','w'};
char name_push[4]={'S','N','E','W'};
//
struct Node
{
    int B_x, B_y;
    int P_x, P_y;
    int step;
    char path[N*N*N];

    Node(int x = 0):step(x){}
};

int BFS_to_B(Node& t, int xx ,int yy)
{
    queue<Node> q;
    Node temp, Front ;

    temp = t;
    q.push(temp);

    memset(vis2, 0 ,sizeof(vis2));
    vis2[t.P_x][t.P_y] = 1;
    vis2[t.B_x][t.B_y] = 1;

    while( !q.empty())
    {
        Front  = q.front();
        q.pop();

        if( Front.P_x == xx  && Front.P_y == yy )
        {
              t = Front;
               return 1;
        }

        for( int i =  0 ;i < 4 ; i++ )
        {
            temp = Front;
            int x = temp.P_x + dirc[i][0];
            int y = temp.P_y + dirc[i][1];

            if( x>=1 && x<=r && y>=1 && y<=c && Map[x][y]!='#' && !vis2[x][y] )
            {

                temp.P_x = x;
                temp.P_y = y;

                temp.path[ temp.step++ ] = name_walk[i];
                q.push(temp);
                vis2[x][y] = 1;
            }
        }

    }

    return 0;
}
int BFS_to_T( Node& t )
{
    queue<Node>q;
    Node temp ,Front;

    temp = t;
    q.push(temp);

    memset(vis1, 0 ,sizeof(vis1));
    vis1[t.B_x][t.B_y] = 1;

    while(!q.empty())
    {

        Front = q.front();
        q.pop();


        if( Map[ Front.B_x ][ Front.B_y ] == 'T' )
        {
             for(int i = 0 ;i < Front.step ;i++)
                 cout << Front.path[i];
            cout << endl << endl;

            return 1;
        }

        for(int i =  0 ;i < 4 ;i++)
        {
            temp = Front;

            /*
            printf(" Front.P_x is %d ,Front.P_y is %d    ", Front.P_x, Front.P_y);
            printf("Front.B_x is %d , Front.B_y is %d\n ", Front.B_x, Front.B_y);
            */

            int x = Front.B_x + dirc[i][0];
            int y = Front.B_y + dirc[i][1];


            int xx = Front.B_x - dirc[i][0];
            int yy = Front.B_y - dirc[i][1];

            if( x>=1 && x<=r && y>=1 && y<=c && Map[x][y]!='#' && xx>=1 && xx<=r && yy>=1 && yy<=c && Map[xx][yy] != '#' && !vis1[x][y])
            {

                if( BFS_to_B( temp, xx, yy ))
                {
                     temp.B_x = x;
                     temp.B_y = y;

                    //cout << Front.B_x << "and" << Front.B_y << endl;
                    temp.P_x = Front.B_x;
                    temp.P_y = Front.B_y;

                    temp.path[temp.step++] = name_push[i];

                    q.push(temp);
                    vis1[x][y] = 1;
                    /*
                   printf("temp.P_x is %d ,temp.P_y is %d    ", temp.P_x, temp.P_y);
                    printf("temp.B_x is %d , temp.B_y is %d\n ", temp.B_x, temp.B_y);
                    cout << "---------------------" << endl;
                    */
                }

            }


          }
      }


    cout <<  "Impossible." << endl << endl;
    return 0;


}
int main()
{
    int Maze = 0;
    while(cin >> r >> c)
    {
        Node First;
        if(!r && !c)
            break;
        Maze++;
        for(int i = 1 ;i <= r ; i++)
            for(int j = 1 ;j <= c ;j++)
            {
                  cin >> Map[i][j];
                if( Map[i][j] == 'B' )
                    First.B_x = i , First.B_y = j;
                if( Map[i][j] == 'S' )
                    First.P_x = i,  First.P_y =j;
            }
        printf("Maze #%d\n",Maze);
        BFS_to_T(First);

    }

   return 0;
}
/*
1 4
SB.T
*/

/*
5 1
.
B
S
.
T
*/



 

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