给出n*m矩阵
给出k个障碍,两坐标之间存在墙或门,门最多10种,
给出s个钥匙位置及编号,相应的钥匙开相应的门
状压BFS即可,注意有可能同一个位置有多个门或者多个钥匙
#include "stdio.h"
#include "string.h"
#include "queue"
using namespace std;
int b[]={1,2,4,8,16,32,64,128,256,512,1024,2048};
int dir[4][2]={{1,0},{-1,0},{0,1},{0,-1}};
struct node
{
int x,y,step,key;
};
int wall[51][51][51][51],map[101][101],hash[51][51][2050];
int n,m;
int bfs()
{
queue<node>q;
node cur,next;
int i,w;
cur.x=1;
cur.y=1;
cur.step=0;
cur.key=0;
cur.key|=map[1][1];
q.push(cur);
memset(hash,0,sizeof(hash));
hash[1][1][cur.key]=1;
while (!q.empty())
{
cur=q.front();
q.pop();
for (i=0;i<4;i++)
{
next.x=cur.x+dir[i][0];
next.y=cur.y+dir[i][1];
if (next.x<1 || next.y<1 || next.x>n || next.y>m) continue;
w=wall[cur.x][cur.y][next.x][next.y];
if ((w&1)==1) continue;
if (w>0 && ((cur.key&w)!=w) ) continue;
next.key=cur.key;
next.key|=map[next.x][next.y];
if (hash[next.x][next.y][next.key]==1) continue;
hash[next.x][next.y][next.key]=1;
next.step=cur.step+1;
if (next.x==n && next.y==m) return next.step;
q.push(next);
}
}
return -1;
}
int main()
{
int k,i,x1,x2,y1,y2,g,s,x,y,p;
while (scanf("%d%d%d",&n,&m,&p)!=EOF)
{
scanf("%d",&k);
memset(wall,0,sizeof(wall));
for (i=1;i<=k;i++)
{
scanf("%d%d%d%d%d",&x1,&y1,&x2,&y2,&g);
wall[x1][y1][x2][y2]|=b[g];
wall[x2][y2][x1][y1]|=b[g];
}
memset(map,0,sizeof(map));
scanf("%d",&s);
for (i=1;i<=s;i++)
{
scanf("%d%d%d",&x,&y,&g);
map[x][y]|=b[g];
}
if (n==1 && m==1){ printf("0\n"); continue;}
printf("%d\n",bfs());
}
return 0;
}