题目链接:

http://acm.hdu.edu.cn/showproblem.php?pid=1885

题目意思:

给一个矩阵,给一个起点多个终点,有些点有墙不能通过,有些点的位置有门,需要拿到相应颜色的钥匙才能打开,问到达终点的最短步数。

解题思路:

BFS+状态压缩。

将每种颜色对应一个二进制数位,1表示已经得到该颜色的钥匙,0表示没有得到。

一把钥匙可以同种颜色的多扇门。

代码:

#include<iostream>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<string>
#include<cstring>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<stack>
#include<list>
#include<queue>
#define eps 1e-6
#define INF 0x1f1f1f1f
#define PI acos(-1.0)
#define ll __int64
#define lson l,m,(rt<<1)
#define rson m+1,r,(rt<<1)|1
//#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std; /*
freopen("data.in","r",stdin);
freopen("data.out","w",stdout);
*/ map<char,int>myp1,myp2; bool vis[20][110][110];
char save[110][110];
int n,m,dir[4][2]={{-1,0},{0,1},{1,0},{0,-1}}; struct Point
{
int x,y,step,ss;
}s; bool iscan(int x,int y)
{
if(x<1||x>n||y<1||y>m||save[x][y]=='#')
return false;
return true;
}
//一把钥匙可以开颜色相同的多种锁
void bfs()
{
memset(vis,false,sizeof(vis));
s.step=0,s.ss=0;
queue<Point>myq; myq.push(s);
vis[0][s.x][s.y]=true;
while(!myq.empty())
{
Point tmp=myq.front();
myq.pop(); int xx,yy; for(int i=0;i<4;i++)
{
xx=tmp.x+dir[i][0],yy=tmp.y+dir[i][1];
if(!iscan(xx,yy))
continue;
if(save[xx][yy]=='X')
{
printf("Escape possible in %d steps.\n",tmp.step+1);
return ;
} int tt=tmp.ss;
if(myp1.find(save[xx][yy])!=myp1.end()) //得到一把钥匙
{
tt=tt|(1<<myp1[save[xx][yy]]);
if(vis[tt][xx][yy]) //该状态之前已被访问
continue;
}
else if(myp2.find(save[xx][yy])!=myp2.end())
{
if(!(tt&(1<<myp2[save[xx][yy]]))) //没有钥匙
continue;
}
if(vis[tt][xx][yy])
continue;
vis[tt][xx][yy]=true;
Point t;
t.x=xx,t.y=yy,t.ss=tt,t.step=tmp.step+1;
myq.push(t);
}
}
printf("The poor student is trapped!\n");
return ;
} int main()
{
myp1['b']=0,myp1['y']=1,myp1['r']=2,myp1['g']=3; //每种不同的颜色对应不同的数位
myp2['B']=0,myp2['Y']=1,myp2['R']=2,myp2['G']=3; while(scanf("%d%d",&n,&m)&&m+n)
{
memset(vis,false,sizeof(vis));
for(int i=1;i<=n;i++)
{
scanf("%s",save[i]+1);
for(int j=1;j<=m;j++)
{
if(save[i][j]=='*')
s.x=i,s.y=j;
}
}
bfs();
} return 0;
}

BFS+状态压缩 hdu-1885-Key Task的更多相关文章

  1. HDU 1885 Key Task (带门和钥匙的迷宫搜索 bfs+二进制压缩)

    传送门: http://acm.hdu.edu.cn/showproblem.php?pid=1885 Key Task Time Limit: 3000/1000 MS (Java/Others)  ...

  2. hdu 1885 Key Task

    题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=1885 Key Task Description The Czech Technical Univers ...

  3. HDU 1885 Key Task (BFS + 状态压缩)

    题意:给定一个n*m的矩阵,里面有门,有钥匙,有出口,问你逃出去的最短路径是多少. 析:这很明显是一个BFS,但是,里面又有其他的东西,所以我们考虑状态压缩,定义三维BFS,最后一维表示拿到钥匙的状态 ...

  4. HDU 1885 Key Task(三维BFS)

    题目链接 题意 : 出口不止一个,一共有四种颜色不同的门由大写字母表示,而钥匙则是对应的小写字母,当你走到门前边的位置时,如果你已经走过相应的钥匙的位置这个门就可以走,只要获得一把钥匙就可以开所有同颜 ...

  5. HDU 1885 Key Task 国家压缩+搜索

    点击打开链接 Key Task Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

  6. hdu 1885 Key Task(bfs+状态压缩)

    Problem Description The Czech Technical University years of its existence . Some of the university b ...

  7. hdu 1885 Key Task (三维bfs)

    题目 之前比赛的一个题, 当时是崔老师做的,今天我自己做了一下.... 还要注意用bfs的时候  有时候并不是最先到达的就是答案,比如HDU 3442 这道题是要求最小的消耗血量伤害,但是并不是最先到 ...

  8. hdu 1885 Key Task(bfs+位运算)

    题意:矩阵中'#'表示墙,'.'表示通路,要求从起点'*'到达终点'X',途中可能遇到一些门(大写字母),要想经过,必须有对应的钥匙(小写字母).问能否完成,若能,花费的时间是多少. 分析:同hdu ...

  9. hdu 1885 Key Task(bfs)

    http://acm.hdu.edu.cn/showproblem.php?pid=1885 再贴一个链接http://blog.csdn.net/u013081425/article/details ...

随机推荐

  1. rpc远程调用开发

    RPC即远程过程调用,适用于集群管理,集群节点就是RPCServer,而我们发起远程调用的web服务器就是RPCClient.所以是少数rpcClient(可能一个)对多个RPCServer(集群节点 ...

  2. poj 3185 The Water Bowls

    The Water Bowls 题意:给定20个01串(最终的状态),每个点变化时会影响左右点,问最终是20个0所需最少操作数? 水题..直接修改增广矩阵即可:看来最优解不是用高斯消元(若是有Gaus ...

  3. C语言-02基本运算

    1.除法运算 / 整数除于整数,还是整数.参与运算的操作数必须是同类型. 1/2的值是0.参与运算的操作数是什么类型,得出的值就是什么类型.   10.5 + 10将右边的10提升为了double类型 ...

  4. MINA源码阅读之ACP

    Processor在XXAcceptor以及XXConnector中所扮演的只能就是:作为Acceptor以及Connetor所创建的Session的Processor: IoAcceptor作为他所 ...

  5. 《Linux命令行大全》系列(二、导航)

    文件系统的导航,是一个不断访问树形结构中节点的过程. 文件系统树 Linux只有一个倒立的文件系统树 不同设备可以挂载到这同一个树上 文件和子目录是此树的组成部分,最顶层的即根目录 目录 根据树节点间 ...

  6. java 堆与栈的区别

    1. 堆与栈的区别? 1-1. 数据存放位置:   数据都存放于RAM (Random Access Memory). 1-2. 存放数据的类型:stack栈中保存方法中的基本数据类型(int, do ...

  7. 【HDU 4436】 str2int (广义SAM)

    str2int Problem Description In this problem, you are given several strings that contain only digits ...

  8. C++的try catch到底能防止什么错误?

    我在.h文件里定义:    LoadingWidget* w;然后.cpp文件里定义: void MyClass::ModifyTask(){    // w = new LoadingWidget( ...

  9. bzoj1079

    50%的数据很好考虑,基本的dp了 关键到了100%,如果用每种颜色有ci种这种常规的写法,显然5^15会爆空间 考虑到反过来,ci<=5, 15^5是不会爆空间的 又想到,每一种颜色,如果数量 ...

  10. Android Loader详解二:使用加载器

    一个使用装载器的应用会典型的包含如下组件: 一个Activity或Fragment. 一个LoaderManager的实例. 一个加载被ContentProvider所支持的数据的CursorLoad ...