hdu 1885 Key Task (三维bfs)

题目

之前比赛的一个题, 当时是崔老师做的,今天我自己做了一下。。。。

还要注意用bfs的时候  有时候并不是最先到达的就是答案,比如HDU 3442 这道题是要求最小的消耗血量伤害,但是并不是最先到达目标点的路径

就是最小的伤害,因为每一个点的伤害是 不一样的, 这种情况要用优先队列优化, 对伤害优化。

题意:*开始, X出口, b, y, r, g 代表钥匙,分别可以开B, Y, R, G颜色的门, 钥匙可以多次使用。问最短的步骤。

思路:vis[][]【】数组开三维,第三维记录状态 是否拿到该颜色的钥匙, 如果以相同的状态走到 相同的地方 就是重复,不能加进队列。

第三维用 二进制下相应的位来表示 是否拿到相应的钥匙。

 #include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <cmath>
#include <algorithm>
using namespace std;
const int maxn = +;
int vis[maxn][maxn][], r, c;
char G[maxn][maxn];
int dx[] = {,,,-};
int dy[] = {,-,,};
char k[] = {'b', 'y', 'r', 'g'};
char d[] = {'B', 'Y', 'R', 'G'};
struct node
{
int x, y, key, step;
} next, pos; void bfs(int a, int b)
{
int i, j;
queue<node>q;
memset(vis, , sizeof(vis));
next.x = a;
next.y = b;
next.key = ;
next.step = ;
q.push(next);
vis[a][b][next.key] = ;
while(!q.empty())
{
pos = q.front();
q.pop();
for(i = ; i < ; i++)
{
next.x = pos.x+dx[i];
next.y = pos.y+dy[i];
next.step = pos.step+;
if(!(next.x>=&&next.x<=r&&next.y>=&&next.y<=c))
continue;
if(G[pos.x][pos.y]=='X')
{
printf("Escape possible in %d steps.\n", pos.step);
return;
}
if(G[next.x][next.y]=='#')
continue;
if(G[next.x][next.y]>='a' && G[next.x][next.y]<='z')
{
for(j = ; j < ; j++)
if(G[next.x][next.y]==k[j])
next.key = (pos.key|(<<j));
}
if(G[next.x][next.y]=='.'||G[next.x][next.y]=='*')
{
next.key = pos.key;
}
if(G[next.x][next.y]>='A' && G[next.x][next.y]<='Z')
{
for(j = ; j < ; j++)
if(G[next.x][next.y]==d[j])
{
if(pos.key&(<<j))
next.key = pos.key;
else
break;
}
if(j<)
continue;
}
if(vis[next.x][next.y][next.key]==)
{
vis[next.x][next.y][next.key] = ;
q.push(next);
}
}
}
printf("The poor student is trapped!\n");
}
int main()
{
int i, j;
int a, b;
while(cin>>r>>c)
{
if(r== && c==) break;
for(i = ; i <= r; i++)
{
getchar();
for(j = ; j <= c; j++)
{
cin>>G[i][j];
if(G[i][j]=='*')
{
a = i;
b = j;
}
}
}
bfs(a, b);
}
return ;
}
上一篇:Linux系统GCC常用命令和GCC编译过程描述


下一篇:visual studio 容器工具首次加载太慢 vsdbg\vs2017u5 exists, deleting 的解决方案