HDU1429胜利大逃亡(续)BFS+状态压缩

这题的算是BFS中应用状压的一个模板题吧,没啥难度,用key来存储已获得的钥匙,状压一下就可以了

不过我写的过程中,犯了好多SB错误,导致调试了好久才A,本来仔细可以1A的说

#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <climits>
#include <string>
#include <iostream>
#include <cstdlib>
#include <list>
#include <set>
#include <queue>
#include <stack>
using namespace std;
#define INF 0xfffffff
#define maxn 30
int n,m,t;
int vis[maxn][maxn][1500];
int dir[4][2]={-1,0,0,-1,1,0,0,1};
struct point
{
    int x,y;
    int state,key;
}s;
char map[maxn][maxn];
int bfs()
{
    memset(vis,0,sizeof(vis));
    queue<point>q;
    q.push(s);
    vis[s.x][s.y][0]=1;
    while(!q.empty())
    {
        point u=q.front();
        q.pop();
        point tmp;
        //printf("//%d %d//\n",u.x,u.y);
        for(int i=0;i<4;i++)
        {
            tmp.x=u.x+dir[i][0];
            tmp.y=u.y+dir[i][1];
            tmp.key=u.key;
            tmp.state=u.state+1;
            //printf("x=%d y=%d key=%d state=%d\n",tmp.x,tmp.y,tmp.key,tmp.state);
            if(tmp.state>=t||tmp.x<0||tmp.x>n-1||tmp.y<0||tmp.y>m-1||map[tmp.x][tmp.y]=='*') continue;
            char tc=map[tmp.x][tmp.y];
            if(tc=='^') return tmp.state;
            if(tc>='A'&&tc<='J')
            {
                //printf("%d %d\n",tmp.key,1<<(tc-'A'));
                if((tmp.key&(1<<(tc-'A')))==0) continue;//等于号前面的括号不要忘记打,在这里我都快调哭了
            }
            else if(tc>='a'&&tc<='j')
            {
                tmp.key|=(1<<(tc-'a'));
            }
            if(vis[tmp.x][tmp.y][tmp.key]==0)
            {
                vis[tmp.x][tmp.y][tmp.key]=1;
                //printf("rudui:%d %d\n",tmp.x,tmp.y);
                q.push(tmp);
            }
        }
    }
    return -1;
}
int main()
{
    while(scanf("%d%d%d",&n,&m,&t)!=EOF)
    {
        for(int i=0;i<n;i++)
        {
            scanf("%s",map[i]);
            for(int j=0;j<m;j++)
            {
                if(map[i][j]=='@')
                {
                    s.x=i;
                    s.y=j;
                }
            }
        }
        s.key=0;s.state=0;
        int ans=bfs();
        if(ans==-1) printf("-1\n");
        else if(ans<t) printf("%d\n",ans);
        else printf("-1\n");
    }
    return 0;
}
时间: 2025-01-06 21:18:43

HDU1429胜利大逃亡(续)BFS+状态压缩的相关文章

HDU1429 胜利大逃亡(续)(BFS+状态压缩)

题目链接:点击打开链接 题意:迷宫中,一个起点,一个终点,迷宫中有墙,有门,门的钥匙也在迷宫中某处,只有拿到钥匙才能打开门,问能不能再T步(不含)之内逃出迷宫. 题解:在朴素BFS上增加了钥匙的状态,只有有钥匙才能打开门,总共有不超过10吧钥匙,所以用一个int的整数的二进制即可存储钥匙的状态.碰到门先判断状态,碰到钥匙更新状态. 代码: #include<iostream> #include<cstdio> #include<cstring> #include<

hdu1429胜利大逃亡(续)(状态压缩+bfs)

题目链接: 啊哈哈,点我点我 题意及思路 最开始我以为跟普通的bfs一样,所以直接写了一个朴素的bfs,一跑,前两组数据对了,但是第三组不对,一看,走过的还可以走啊,所以不能标记,结果我的bfs乱改,最后 毫无疑问改成了死循环.所以看题解... 思路:因为有10中不同的钥匙,每种都有两种状态,所以结合计算机是二进制保存的特点,刚好把这10把钥匙当成每一个为,要要1<<10个位保存所有的状态,然后就是模拟捡起钥匙,捡起钥匙就是说明这个位上的数字变成1这个状态,所以自然而然想到了位运算,只要|一下

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

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1429 思路分析:题目要求找出最短的逃亡路径,但是与一般的问题不同,该问题增加了门与钥匙约束条件: 考虑一般的搜索问题的解答思路: 搜索算法即在解空间中搜索满足要求的答案,可以看做一棵不断生长的状态树,状态之间不断扩展出新的状态,直到找出所需要的状态,即答案: <1>定义状态:对于该问题,由于存在门与锁的约束条件,所以状态应该包括3个元素,即人所在的坐标 x 和 y 以及含有锁的种类: <2&

hdu - 1429 胜利大逃亡(续) (bfs状态压缩)

http://acm.hdu.edu.cn/showproblem.php?pid=1429 终于开始能够做状态压缩的题了,虽然这只是状态压缩里面一道很简单的题. 状态压缩就是用二进制的思想来表示状态. 总共有10种钥匙,那么开一个(1<<10 的数组) 那么每次遇到一把钥匙我就用当前状态 |  钥匙转化为2进制的数值,然后遇到门的时候判断是否有对应的钥匙,只要用当前状态 & 门转化为2进制的值就可以.初始为0时,state=0,表示10个状态位都是0.那么每次遇到钥匙就改变相应的状态

胜利大逃亡(续)(状态压缩bfs)

胜利大逃亡(续) Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 7357    Accepted Submission(s): 2552 Problem Description Ignatius再次被魔王抓走了(搞不懂他咋这么讨魔王喜欢)……这次魔王汲取了上次的教训,把Ignatius关在一个n*m的地牢里,并在地牢的某些地方安装了带

hdu--1429--胜利大逃亡(续) (bfs+状态压缩)

胜利大逃亡(续) Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 8560    Accepted Submission(s): 3071 Problem Description Ignatius再次被魔王抓走了(搞不懂他咋这么讨魔王喜欢)-- 这次魔王汲取了上次的教训,把Ignatius关在一个n*m的地牢里,并在地牢的某些地方安装了带

hdu 1429 胜利大逃亡(续)(bfs+位压缩)

胜利大逃亡(续) Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 7346    Accepted Submission(s): 2546 Problem Description Ignatius再次被魔王抓走了(搞不懂他咋这么讨魔王喜欢)…… 这次魔王汲取了上次的教训,把Ignatius关在一个n*m的地牢里,并在地牢的某些地方安装了带

hdu 1429 胜利大逃亡(续) 搜索+状态压缩,,不错的题。

胜利大逃亡(续) Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 5860    Accepted Submission(s): 2046 Problem Description Ignatius再次被魔王抓走了(搞不懂他咋这么讨魔王喜欢)-- 这次魔王汲取了上次的教训,把Ignatius关在一个n*m的地牢里,并在地牢的某些地方安装了

HDU1429 胜利大逃亡(续) BFS +简单状压

把手中持有的钥匙状态状压一下即可,然后vis访问标记的时候,开个三维,多一维即为当前持有钥匙状态,这样就能祛除重复标记困难走点的问题,跟网络赛那题很像,网络赛的更难点,这个简单点 int n,m,t; int sx,sy,ex,ey; char mp[20 + 55][20 + 55]; bool vis[20 + 5][20 + 5][(1<<10) + 5]; int dir[4][2] = {{1,0},{0,1},{-1,0},{0,-1}}; struct Node { int no