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

终于开始能够做状态压缩的题了,虽然这只是状态压缩里面一道很简单的题.

状态压缩就是用二进制的思想来表示状态.

总共有10种钥匙,那么开一个(1<<10 的数组) 那么每次遇到一把钥匙我就用当前状态 |  钥匙转化为2进制的数值,然后遇到门的时候判断是否有对应的钥匙,只要用当前状态 & 门转化为2进制的值就可以。初始为0时,state=0,表示10个状态位都是0.那么每次遇到钥匙就改变相应的状态位。

比如当前state ==0  遇到 'a' 那么 state | 0 ==1 (1),遇上 'b'那么state | 1 ==3  (11)

这样每遇到一把钥匙,当前状态对应的位就变成1.

其余的就跟普通bfs没什么两样了。

#include <iostream>
#include <cstdio>
#include <cmath>
#include <vector>
#include <cstring>
#include <string>
#include <algorithm>
#include <string>
#include <set>
#include <functional>
#include <numeric>
#include <sstream>
#include <stack>
#include <map>
#include <queue>
#pragma comment(linker, "/STACK:102400000,102400000")
#define CL(arr, val) memset(arr, val, sizeof(arr)) #define ll long long
#define inf 0x7f7f7f7f
#define lc l,m,rt<<1
#define rc m + 1,r,rt<<1|1
#define pi acos(-1.0) #define L(x) (x) << 1
#define R(x) (x) << 1 | 1
#define MID(l, r) (l + r) >> 1
#define Min(x, y) (x) < (y) ? (x) : (y)
#define Max(x, y) (x) < (y) ? (y) : (x)
#define E(x) (1 << (x))
#define iabs(x) (x) < 0 ? -(x) : (x)
#define OUT(x) printf("%I64d\n", x)
#define lowbit(x) (x)&(-x)
#define Read() freopen("a.txt", "r", stdin)
#define Write() freopen("b.txt", "w", stdout);
#define maxn 1000000000
#define N 2510
#define mod 1000000000
using namespace std; struct point
{
int x,y,step,state;
}; int n,m,t;
int dir[][]={-,,,,,,,-};
char maze[][];
int vis[][][<<];
int ex,ey; int get(char c)
{
return c-(islower(c)?'a':'A'); //转化为 数字 'a'为0
}
void bfs(int sx,int sy)
{
point s;
s.x=sx,s.y=sy,s.step=,s.state=;
memset(vis,,sizeof(vis));
vis[s.x][s.y][]=;
queue<point>que;
que.push(s);
while(!que.empty())
{
point e=que.front(); que.pop();
// printf("%d %d %d %d\n",e.x,e.y,e.step,e.state);
if(e.x==ex&&e.y==ey) {printf("%d\n",e.step);return;}
for(int i=;i<;i++)
{
s.x=e.x+dir[i][];
s.y=e.y+dir[i][];
s.state=e.state;
if(s.x>=&&s.x<n&&s.y>=&&s.y<m&&maze[s.x][s.y]!='*')
{
//判断是否有相应钥匙
if(isupper(maze[s.x][s.y])&&(!(e.state&(<<get(maze[s.x][s.y]))))) continue;
if(islower(maze[s.x][s.y])) //遇到钥匙
{
//printf("%d\n",1<<get(maze[s.x][s.y]));
s.state|=(<<get(maze[s.x][s.y]));
}
s.step=e.step+;
if(!vis[s.x][s.y][s.state]&&s.step<=t)
{
vis[s.x][s.y][s.state]=;
que.push(s);
}
}
}
}
printf("-1\n");
}
int main()
{
//freopen("a.txt","r",stdin);
int sx,sy;
while(~scanf("%d%d%d",&n,&m,&t))
{
t--;
for(int i=;i<n;i++)
{
scanf("%s",maze[i]);
for(int j=;j<m;j++)
if(maze[i][j]=='@')
{
sx=i,sy=j;
}
else if(maze[i][j]=='^')
{
ex=i,ey=j;
}
}
// printf("%d %d\n",sx,sy);
bfs(sx,sy);
}
return ;
}

最新文章

  1. OpenGL坐标变换及其数学原理,两种摄像机交互模型(附源程序)
  2. 《On Lisp》第四章第三节图4.3中的prune函数fix
  3. Java-马士兵设计模式学习笔记-观察者模式-OOD线程
  4. Poj 2993 Emag eht htiw Em Pleh
  5. js和HTML结合(补充知识:如何防止文件缓存的js代码)
  6. bzoj1061: [Noi2008]志愿者招募
  7. C++程序设计实践指导1.10二维数组元素换位改写要求实现
  8. POJ 2195 Going Home (带权二分图匹配)
  9. JavaScript判断对象类型及节点类型、节点名称和节点值
  10. C# this扩展方法
  11. python输入
  12. anaconda3下64位python和32位python共存
  13. 学习PHPExcel
  14. 使用PsExec获取shell执行命令
  15. spring boot 错误处理之深度历险
  16. MySQL中的事务及读写锁实现并发访问控制
  17. svg矢量图在flex布局中样式扭曲的问题
  18. Python数值计算之插值曲线拟合-01
  19. python下安装lxml
  20. Ubuntu 13.10 安装软件失败后出现的问题——已安装 post-installation 脚本 返回了错误号 1

热门文章

  1. [转]查询表达式 (F#)
  2. spark shuffle:分区原理及相关的疑问
  3. rabbitmq在storm中使用
  4. 手动将Excel数据导入SQL
  5. JPA调用存储过程
  6. 迅为I.MX6DL开发板飞思卡尔Freescale Cortex A9 迅为-iMX6双核核心板
  7. shellinabox的安装使用
  8. CS2QS
  9. 使用 reduce 实现数组 map 方法
  10. 获取select标签选中的值的三种方式