給出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() { queueq; 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; }