• HDU 1429 胜利大逃亡(续) (bfs+状态压缩)


    胜利大逃亡(续)

    题目链接:

    http://acm.hust.edu.cn/vjudge/contest/71151#problem/D

    Description

    Ignatius再次被魔王抓走了(搞不懂他咋这么讨魔王喜欢)…… 这次魔王汲取了上次的教训,把Ignatius关在一个n*m的地牢里,并在地牢的某些地方安装了带锁的门,钥匙藏在地牢另外的某些地方。刚开始Ignatius被关在(sx,sy)的位置,离开地牢的门在(ex,ey)的位置。Ignatius每分钟只能从一个坐标走到相邻四个坐标中的其中一个。魔王每t分钟回地牢视察一次,若发现Ignatius不在原位置便把他拎回去。经过若干次的尝试,Ignatius已画出整个地牢的地图。现在请你帮他计算能否再次成功逃亡。只要在魔王下次视察之前走到出口就算离开地牢,如果魔王回来的时候刚好走到出口或还未到出口都算逃亡失败。

    Input

    每组测试数据的第一行有三个整数n,m,t(2<=n,m<=20,t > 0)。接下来的n行m列为地牢的地图,其中包括: ``` . 代表路 * 代表墙 @ 代表Ignatius的起始位置 ^ 代表地牢的出口 A-J 代表带锁的门,对应的钥匙分别为a-j a-j 代表钥匙,对应的门分别为A-J ``` 每组测试数据之间有一个空行。

    Output

    针对每组测试数据,如果可以成功逃亡,请输出需要多少分钟才能离开,如果不能则输出-1。

    Sample Input

    ``` 4 5 17 @A.B. a*.*. *..*^ c..b*

    4 5 16
    @A.B.
    a..
    ..^
    c..b*

    </big>
    
    ##Sample Output
    <big>
    

    16
    -1

    </big>
    
    
    
    
    
    <br/>
    ##题意:
    <big>
    在n*m的地图上,有10种类型的门及其对应钥匙,求最少的时间从起点到达终点,T-1内不能到达则输出-1.
    </big>
    
    
    <br/>
    ##题解:
    <big>
    类似魔塔的搜索题,这里用bfs来搜最小步数即可. 用状态压缩处理每个位置拿到的钥匙状态.
    判重:除了点坐标外,需要额外记录达到当前点的钥匙状态. (因为有些位置可能重复到达).
    </big>
    
    
    
    
    <br/>
    ##代码:
    ``` cpp
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #include <queue>
    #include <map>
    #include <set>
    #include <stack>
    #include <vector>
    #include <list>
    #define LL long long
    #define eps 1e-8
    #define maxn 25
    #define mod 100000007
    #define inf 0x3f3f3f3f
    #define mid(a,b) ((a+b)>>1)
    #define IN freopen("in.txt","r",stdin);
    using namespace std;
    
    int n, m, T;
    char mp[maxn][maxn];
    bool vis[maxn][maxn][1<<10];
    
    bool is_ok(int x, int y) {
        return x>=0 && y>=0 && x<n && y<m;
    }
    
    struct node {
        int x,y;
        int step, key;
    };
    int dir[4][2] = {{0,1},{0,-1},{1,0},{-1,0}};
    
    int bfs(int sx, int sy) {
        queue<node> q;
        while(!q.empty()) q.pop();
        node cur, next;
        cur.x = sx, cur.y = sy, cur.step = 0, cur.key = 0;
        q.push(cur);
        vis[sx][sy][0] = 1;
    
        while(!q.empty()) {
            cur = q.front(); q.pop();
    
            for(int i=0; i<4; i++) {
                int xx = cur.x + dir[i][0];
                int yy = cur.y + dir[i][1];
                if(!is_ok(xx,yy) || mp[xx][yy]=='*') continue;
                next.x = xx, next.y = yy, next.step = cur.step + 1; next.key = cur.key;
    
                if(next.step == T) continue;
                if(mp[xx][yy] == '^') return next.step;
    
                if(mp[xx][yy]>='a' && mp[xx][yy]<='z') {
                    next.key |= (1 << (mp[xx][yy]-'a'));
                }
    
                if(mp[xx][yy]>='A' && mp[xx][yy]<='Z') {
                    if((next.key & (1 << (mp[xx][yy]-'A'))) == 0)
                        continue;
                }
    
                if(vis[next.x][next.y][next.key]) continue;
                vis[next.x][next.y][next.key] = 1;
                q.push(next);
            }
        }
    
        return -1;
    }
    
    int main(int argc, char const *argv[])
    {
        //IN;
    
        while(scanf("%d %d %d", &n,&m,&T) != EOF)
        {
            for(int i=0; i<n; i++)
                scanf("%s", mp[i]);
    
            int sx = -1, sy = -1;
            for(int i=0; i<n; i++) {
                for(int j=0; j<m; j++) if(mp[i][j] == '@') {
                    sx = i, sy = j; break;
                }
                if(sx != -1) break;
            }
    
            memset(vis, 0, sizeof(vis));
            int ans = bfs(sx, sy);
    
            printf("%d
    ", ans);
        }
    
        return 0;
    }
    
  • 相关阅读:
    day7 反射
    day7 面向对象进阶
    day7 面向对象class()学习
    day6 subprocess模块、logging模块
    day6 hashlib模块
    day6 ConfigParser模块 yaml模块
    day6 xml文件格式的处理
    day6 shelve模块
    day6 SYS模块
    Servlet的学习之Response响应对象(1)
  • 原文地址:https://www.cnblogs.com/Sunshine-tcf/p/5799093.html
Copyright © 2020-2023  润新知