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

这道题的钥匙只有10个,可以压成二进制

这里有有句非常关键的话

(k & door[x][y]) == door[x][y]

一开始以为只要(k & door[x][y]) ==1就可以了

后来发现如果door[x][y]为0的话,这句话就不对了。

所以要包含这里没有门的情况

所以要这么写

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<cstring>
#define REP(i, a, b) for(int i = (a); i < (b); i++)
#define _for(i, a, b) for(int i = (a); i <= (b); i++)
using namespace std;

const int MAXN = 25;
struct node { int x, y, step, key; };
int key[MAXN][MAXN], door[MAXN][MAXN], vis[MAXN][MAXN][1050];
int arr[MAXN][MAXN], sx, sy, ex, ey, n, m, t;
int dir[4][2] = {0, 1, 0, -1, -1, 0, 1, 0};

bool judge(int x, int y, int k)
{
	if(!(0 <= x && x < n && 0 <= y && y < m)) return false;
	if(vis[x][y][k] || arr[x][y]) return false;
	if(!((k & door[x][y]) == door[x][y])) return false;
	return true;	
}

int bfs()
{
	queue<node> q;
	q.push(node{sx, sy, 0, 0});
	vis[sx][sy][0] = 1;
	
	while(!q.empty())
	{
		node u = q.front(); q.pop();
		if(u.x == ex && u.y == ey) return u.step;
		REP(i, 0, 4)
		{
			int x = u.x + dir[i][0], y = u.y + dir[i][1];
			if(!judge(x, y, u.key)) continue;
			int k = u.key | key[x][y];
			vis[x][y][k] = 1;
			q.push(node{x, y, u.step + 1, k});
		}
	}
	return 1e9;
}

int main()
{
	while(~scanf("%d%d%d", &n, &m, &t))
	{
		memset(door, 0, sizeof(door));
		memset(key, 0, sizeof(key));
		memset(vis, 0, sizeof(vis));
		memset(arr, 0, sizeof(arr));
		
		REP(i, 0, n)
		{
			char s[MAXN];
			scanf("%s", s);
			REP(j, 0, m)
			{
				char ch = s[j];
				if(ch == '*') arr[i][j] = 1;
				if(ch == '@') sx = i, sy = j;
				if(ch == '^') ex = i, ey = j;
				if('a' <= ch && ch <= 'z' ) key[i][j] = 1 << (ch - 'a');
				if('A' <= ch && ch <= 'Z' ) door[i][j] = 1 << (ch - 'A');
			}
		}
		
		int ans = bfs();
		printf("%d
", ans < t ? ans : -1);
	}
	
	return 0;
}
原文地址:https://www.cnblogs.com/sugewud/p/9819333.html