您的位置:首页 > 其它

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

2017-03-27 19:13 417 查看
题目传送门

因为只有10把钥匙,所以只需要10位2进制表示拿与没拿到钥匙的状态,使用vis
[m][2000]数组表示每个位置拿到多少钥匙。使用位运算& 和 | 来判断是否有当前位置的钥匙能否打开这个门。其余就是个dfs;

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <cmath>
#include <queue>
using namespace std;
typedef struct node{
int x, y;
int step;
int key;
}STEP;
int vis[30][30][2000],n,m,t;
char ch[30][30];
int N[4][2]={0,1,0,-1,1,0,-1,0};
int bfs(int sx, int sy)
{
queue<STEP>q;
STEP f, next;
f.x = sx;
f.y = sy;
f.step = 0;
q.push(f);
while (!q.empty())
{
next = q.front();
q.pop();
if (ch[next.x][next.y]=='^')
return next.step;
for (int i = 0; i < 4; i++)
{
STEP nx = next;
nx.x += N[i][0];
nx.y += N[i][1];
if (nx.x>=n||nx.x<0||nx.y>=m||nx.y<0)
continue;
if (ch[nx.x][nx.y]=='*')
continue;
nx.step +=1;
if (nx.step>=t)
continue;
if (ch[nx.x][nx.y]>='a'&&ch[nx.x][nx.y]<='z')
{
int t = 1<<(ch[nx.x][nx.y]-'a');
nx.key = next.key|t;
if (!vis[nx.x][nx.y][nx.key])
{
vis[nx.x][nx.y][nx.key]=1;
q.push(nx);
}
}
else if (ch[nx.x][nx.y]>='A'&&ch[nx.x][nx.y]<='Z')
{
int t = 1<<(ch[nx.x][nx.y]-'A');
int nk = next.key&t;
if (nk&&!vis[nx.x][nx.y][nx.key])
{
vis[nx.x][nx.y][nx.key]=1;
q.push(nx);
}
}
else
{
if (!vis[nx.x][nx.y][nx.key])
{
vis[nx.x][nx.y][nx.key]=1;
q.push(nx);
}
}
}
}
return -1;
}
int main(void)
{
int sx,sy;
while (scanf("%d %d %d", &n, &m, &t)!=EOF)
{
memset(vis,0,sizeof(vis));
for (int i = 0; i < n; i++)
{
getchar();
for (int j = 0; j < m; j++)
{
scanf("%c", &ch[i][j]);
if (ch[i][j]=='@')
{
sx=i;
sy=j;
ch[i][j]='.';
}
}
}
printf("%d\n",bfs(sx,sy));
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  bfs 状态压缩 位运算