16
-1
二进制压缩状态,用二进制模拟开锁判重。。
#include <iostream> #include <cstdlib> #include <cstdio> #include <queue> #include <cstring> using namespace std; const int maxn=25; char map[maxn][maxn]; bool vis[maxn][maxn][1025];//10把钥匙,1024种状态; struct Node { int x; int y; int step; int key;//标记当前找到钥匙的状态 }; int sx,sy,ex,ey; int n,m,t; int dx[]={-1,0,1,0}; int dy[]={0,-1,0,1}; bool OK(Node cur) { if(cur.x<0||cur.x>=n||cur.y<0||cur.y>=m) return 0; return 1; } void ReadIn() { int i,j; for(i=0;i<n;i++) { for(j=0;j<m;j++) { cin>>map[i][j]; if(map[i][j]=='@') { sx=i; sy=j; map[i][j]=='.'; } else if(map[i][j]=='^') { ex=i; ey=j; map[i][j]=='.'; } } } } int BFS() { queue<Node>q; memset(vis,0,sizeof(vis)); Node A,B,cur; A.x=sx; A.y=sy; A.step=0; A.key=0; vis[A.x][A.y][A.key]=1; q.push(A); while(!q.empty()) { cur=q.front(); q.pop(); if(cur.step>=t) continue; if(cur.x==ex&&cur.y==ey) return cur.step; for(int i=0;i<4;i++) { B.x=cur.x+dx[i]; B.y=cur.y+dy[i]; B.key=cur.key; B.step=cur.step+1; if(OK(B)&&map[B.x][B.y]!='*') { if(map[B.x][B.y]>='a'&&map[B.x][B.y]<='z') { int key =(1<<(map[B.x][B.y]-'a'));//左移一位,因为0000的意思应该是0001; B.key|=key;//拾取钥匙; if(!vis[B.x][B.y][B.key]) { vis[B.x][B.y][B.key]=1; q.push(B); } } else if(map[B.x][B.y]>='A'&&map[B.x][B.y]<='Z') { int key=(map[B.x][B.y]-'A'); if (((B.key>>key)&1)&&!vis[B.x][B.y][B.key]) {//右移key位后与1,判断是不是存在打开当前门的钥匙 vis[B.x][B.y][B.key]=1; q.push(B); } } else if(!vis[B.x][B.y][B.key]) { vis[B.x][B.y][B.key]=1; q.push(B); } } } } return -1; } int main() { while(scanf("%d%d%d%*c",&n,&m,&t)!=EOF) { ReadIn(); int ans=BFS(); printf("%d\n",ans); } return 0; }