百练oj 拯救公主

广搜,值得学习的地方时是用二进制数来存储已获得的钻石种类。

#include <iostream>
#include <memory.h>
#include <vector>
#include <queue>
#include <stdio.h>
#include <algorithm>
#include <unordered_set>
#include <set>
#define IN  (1<<28)
using namespace std;
struct node
{
    int x,y,step, dia;
    node( int xx = 0, int yy = 0, int ss = 0, int dd = 0 ):x(xx), y(yy), step(ss), dia(dd) {}
    friend bool operator <(const node &a, const node &b )
    {
        return a.step > b.step;
    }
};
struct door
{
    int x,y;
    door( int xx = 0, int yy = 0):x(xx), y(yy) {}
};
door doors[15];
queue<node> q;
int visited[205][205][1<<5], R, C, K, T, BeginX, BeginY, EndX, EndY, cnt;
int dx[] = {1,-1,0,0};
int dy[] = {0,0,1,-1};
char Map[205][205];
void bfs()
{
    if( K > 5 )
    {
        printf("oop!\n");
        return;
    }
    q.push( node( BeginX, BeginY, 0, 0 ) );
    visited[BeginX][BeginY][0] = 1;
    while( !q.empty() )
    {
        node now = q.front();
        q.pop();
        if( now.x == EndX && now.y == EndY && now.dia >= (1<<K) - 1 )
        {
            printf("%d\n", now.step );
            return;
        }
        if( Map[now.x][now.y] == '$' )
        {
            for( int i = 0; i < cnt; i++ )
            {
                if( !visited[ doors[i].x ][ doors[i].y ][ now.dia ] )
                {
                    q.push( node( doors[i].x, doors[i].y, now.step, now.dia ) );
                    visited[ doors[i].x ][ doors[i].y ][ now.dia ] = 1;
                }
            }
        }
        for( int i = 0; i < 4; i++ )
        {
            int nowx = now.x + dx[i];
            int nowy = now.y + dy[i];
            if( Map[nowx][nowy] != '#' )
            {
                if( Map[nowx][nowy] >= '0' && Map[nowx][nowy] <= '4' )
                {
                 int s;
                 s = now.dia | (1<<Map[nowx][nowy]-'0');
                 if( !visited[nowx][nowy][s] )
                 {
                     q.push( node( nowx, nowy, now.step + 1, s ) );
                     visited[nowx][nowy][s] = 1;
                 }
                }
                else
                {
                    if( !visited[nowx][nowy][now.dia] )
                    {
                        q.push( node( nowx, nowy, now.step + 1, now.dia ) );
                        visited[nowx][nowy][now.dia] = 1;
                    }
                }
            }
        }
    }
    printf("oop!\n");
    return;
}
int main()
{
    scanf("%d", &T);
    while( T-- )
    {
        scanf("%d %d %d", &R, &C, &K);
        memset(visited, 0, sizeof(visited));
       for( int i = 0; i < 205; i++ )
        for( int j = 0; j < 205; j++ )
                 Map[i][j] = '0';
        cnt = 0;//传送门数量
        while( !q.empty() )
        {
            q.pop();
        }
        for( int i = 1; i <= R; i++ )
            for( int j = 1; j <= C; j++ )
            {
               cin >> Map[i][j];
                if( Map[i][j] == 'S' )
                {
                    BeginX = i;
                    BeginY = j;
                }
                else if( Map[i][j] == 'E' )
                {
                    EndX = i;
                    EndY = j;
                }
                else if( Map[i][j] == '$' )
                {
                    doors[cnt].x = i;
                    doors[cnt].y = j;
                    cnt++;
                }
            }
        for( int i = 0; i <= R+1; i++ )
            for( int j = 0; j <= C+1; j++ )
        {
            if( i==0 || j==0 || i==R+1 || j==C+1 )
                Map[i][j] = '#';
        }
        bfs();
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/xutian_curry/article/details/80259465
今日推荐