题意:
1944年,特种兵麦克接到国防部的命令,要求立即赶赴太平洋上的一个孤岛,营救被敌军俘虏的大兵瑞恩。瑞恩被关押在一个迷宫里,迷宫地形复杂,但是幸好麦克得到了迷宫的地形图。
迷宫的外形是一个长方形,其在南北方向被划分为N行,在东西方向被划分为M列,于是整个迷宫被划分为N*M个单元。我们用一个有序数对(单元的行号,单元的列号)来表示单元位置。南北或东西方向相邻的两个单元之间可以互通,或者存在一扇锁着的门,又或者存在一堵不可逾越的墙。迷宫中有一些单元存放着钥匙,并且所有的门被分为P类,打开同一类的门的钥匙相同,打开不同类的门的钥匙不同。
大兵瑞恩被关押在迷宫的东南角,即(N,M)单元里,并已经昏迷。迷宫只有一个入口,在西北角,也就是说,麦克可以直接进入(1,1)单元。另外,麦克从一个单元移动到另一个相邻单元的时间为1,拿取所在单元的钥匙的时间以及用钥匙开门的时间忽略不计。
你的任务是帮助麦克以最快的方式抵达瑞恩所在单元,营救大兵瑞恩。
分析:
这个状压体现在key上 我i们用把key状压一下 就能记录到一个点时 已经拥有的key的种类
ban[x1][y1][x2][y1]记录两个点之间的状态 是门 还是墙 还是啥都没有
inc[x][y]记录这个点所存储的钥匙 (可能不止一个 所以要用二进制)
vis[x][y][key] 标记当前点 在拥有的钥匙种类为key时是否走过
代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
//typedef __int128 lll;
#define close() ios::sync_with_stdio(0), cin.tie(0), cout.tie(0)
#define mem(a, b) memset(a, b, sizeof(a))
#define debug(a) cout << "debug :" << a << endl
#define fi first
#define se second
const int maxn = 1e6;
const int inf = 0x3f3f3f3f;
struct node
{
int x, y, key, step;
node(int a = 0, int b = 0, int c = 0, int d = 0) : x(a), y(b), key(c), step(d){}
};
int vis[20][20][10000], wall[20][20][20][20];
int key[20][20];
int n, m, p;
int dir[4][2] = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
void init()
{
mem(wall, -1), mem(vis, 0), mem(key, 0);
}
int bfs()
{
queue<node> q;
q.push(node(1, 1, key[1][1], 0));
vis[1][1][key[1][1]] = 1;
while(!q.empty())
{
node now = q.front(); q.pop();
if(now.x == n && now.y == m) return now.step;
for(int i = 0; i < 4; i++)
{
int x = now.x + dir[i][0], y = now.y + dir[i][1];
if(x < 1 || x > n || y < 1 || y > m || !wall[now.x][now.y][x][y]) continue;
if(wall[now.x][now.y][x][y] == -1 || (now.key & (1 << (wall[now.x][now.y][x][y] - 1))))
{
int nexkey = now.key | key[x][y];
if(vis[x][y][nexkey]) continue;
vis[x][y][nexkey] = 1;
node nex = node(x, y, nexkey, now.step + 1);
q.push(nex);
}
}
}
return -1;
}
int main()
{
while(cin >> n >> m >> p)
{
int k;cin >> k;
init();
while(k--)
{
int x1, y1, x2, y2, wal;
cin >> x1 >> y1 >> x2 >> y2 >> wal;
wall[x1][y1][x2][y2] = wall[x2][y2][x1][y1] = wal;
}
cin >> k;
while(k--)
{
int x, y, ke;
cin >> x >> y >> ke;
key[x][y] |= (1 << (ke - 1));
}
cout << bfs() << endl;
}
}