2014 网选 广州赛区 hdu 5025 Saving Tang Monk(bfs+四维数组记录状态)

简介:

/*
    这是我做过的一道新类型的搜索题!从来没想过用四维数组记录状态!
    以前做过的都是用二维的!自己的四维还是太狭隘了.....
    
    题意:悟空救师傅 ! 在救师父之前要先把所有的钥匙找到!
    每种钥匙有 k 种, 每一种有多个! 只要求找到每一种的其中一个就可以!
    找钥匙的顺序按照 第1种, 第2种, 第3种 ....第k种! 
    找钥匙的时间是一步, 走到相邻空地的时间是一步, 打蛇的时间就是两步!
    求找到师傅的最少步数! 
    
    这里说一下 state[N][N][10][35]表示的含义: ->state[x][y][i][j] 
    前两维就不用说了,就是地图上的坐标, 第三维表示的是当前找到第几把钥匙
    第四维表示的沿着一条路径走到 (x, y)找到 第 i 把钥匙打掉了哪几条蛇!
    将 j 拆分成 二进制, 从右往左数, 如果第 k 为是1, 表示第 k 条 蛇杀掉了! 
*/ 

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>

#define N 105
using namespace std;

char mp[105][105];

bool state[N][N][10][35];

int bx, by;

struct node{
    int x, y;
    int numk, snk;
    int step;
    node(){}
    
    node(int x, int y, int numk, int snk, int step){
        this->x = x;
        this->y = y;
        this->numk = numk;
        this->snk = snk;
        this->step = step;
    }
};

int n, m;
int dir[4][2] = {0, 1, 1, 0, -1, 0, 0, -1};
bool operator < (node a, node b) {
    return a.step > b.step;
}

priority_queue<node>q;

bool bfs(){
    while(!q.empty()) q.pop();
    memset(state, false, sizeof(state));
    q.push( node(bx, by, 0, 0, 0) );
    state[bx][by][0][0] = true;
    while( !q.empty() ) {
        node cur = q.top();
        q.pop();
        for(int i=0; i<4; ++i){
            int x = cur.x + dir[i][0];
            int y = cur.y + dir[i][1];
            if(x<1 || x>n || y<1 || y>n || mp[x][y]=='#') continue;
            int numk = cur.numk, snk = cur.snk, step = cur.step;
            if(mp[x][y] == '.')
                step += 1;
            else if( mp[x][y] >= '1' && mp[x][y] <= '9'){
                if( numk + 1 == mp[x][y] - '0' )
                    numk += 1;
                step += 1;
            }
            else if( mp[x][y] >= 'A' && mp[x][y] <= 'E' ){//这一步是关键 
                int cnt = mp[x][y] - 'A' + 1; 
                if(    (1 << (cnt-1) ) & snk ) step += 1;//如果这一条蛇已经被打过了,也就是一条路又折回到这一个点 
                else{//在这一条路上,这条蛇没有被打过,那就将它打掉,并标记这条蛇打过了! 
                    step += 2;
                    snk ^= ( 1 << (cnt-1) );
                }
            }
            else if( mp[x][y] == 'T' && numk == m ){
                printf("%d\n", step + 1);
                return true;
            }
            else step += 1;
            
            if( state[x][y][numk][snk] )  continue;
            state[x][y][numk][snk] = true;
            q.push( node(x, y, numk, snk, step) );
        }
    }
    return false;
}

int main(){
    while( scanf("%d%d", &n, &m) && (n ||m) ) {
        int cntS = 0;
        for(int i = 1; i <= n; ++ i){
            scanf("%s", mp[i] + 1);
            for(int j = 1; j <=n; ++ j)
                if(mp[i][j] == 'K'){
                    bx = i;
                    by = j;
                }
                else if(mp[i][j] == 'S')
                    mp[i][j] = 'A' + cntS++;
        }
        if( !bfs() )  printf("impossible\n");
    }
    return 0;
}

目录
相关文章
|
算法
【算法挨揍日记】day12——153. 寻找旋转排序数组中的最小值、LCR 173. 点名
已知一个长度为 n 的数组,预先按照升序排列,经由 1 到 n 次 旋转 后,得到输入数组。例如,原数组 nums = [0,1,2,4,5,6,7] 在变化后可能得到:
113 1
|
算法
山东第一届省赛 Greatest Number(优雅暴力+二分)
山东第一届省赛 Greatest Number(优雅暴力+二分)
71 1
(数学)(必要解题步骤)2021icpc上海D. Strange Fractions
(数学)(必要解题步骤)2021icpc上海D. Strange Fractions
81 0
【CCCC】L3-018 森森美图 (30分),计算几何+判断三点共线+bfs最短路
【CCCC】L3-018 森森美图 (30分),计算几何+判断三点共线+bfs最短路
149 0
|
人工智能 Python
2019CCPC厦门站 A. Zayin and Bus(bfs 贪心 排序)
2019CCPC厦门站 A. Zayin and Bus(bfs 贪心 排序)
90 0
|
机器学习/深度学习 算法
2021杭电多校第八场 HDU7064-Singing Superstar(哈希)
2021杭电多校第八场 HDU7064-Singing Superstar(哈希)
79 0
|
机器学习/深度学习
2019CCPC厦门站 H. Zayin and Obstacles(三维前缀和 bfs)
2019CCPC厦门站 H. Zayin and Obstacles(三维前缀和 bfs)
94 0
2015长春网络赛 —— B. Ponds (拓扑排序删点+DFS)
2015长春网络赛 —— B. Ponds (拓扑排序删点+DFS)
88 0
[SDUT 2414] | 山东省第三届省赛 An interesting game | 最小费用最大流
题目描述 Xiao Ming recently designs a little game, in front of player there are N small hillsides put in order, now Xiao Ming wants to increase some hillsides to block the player, so he prepared another M hillsides, but he does not hope it will be too difficult,
164 0
[SDUT 2414] | 山东省第三届省赛 An interesting game | 最小费用最大流
Boring Segments-CF教育场112.尺取+线段树
样例输入: 样例输出 样例输入: 样例输出
87 0
Boring Segments-CF教育场112.尺取+线段树