通过位运算来获取模拟钥匙的拾取和宝箱的开启;如拿到第一把钥匙,即可用Key | 1 来拾取,第二把即 Key|10;
碰到宝箱将Key向右移动 字符 -'A' 位,获取当前位的值来判断是否有对应钥匙;
1 #include<iostream> 2 #include<stdio.h> 3 #include<string.h> 4 #include<queue> 5 using namespace std; 6 int t[4][2]={1,0,-1,0,0,1,0,-1},vist[25][25][5000]; 7 char str[25][25]; 8 int n,m,tj,flag=0,ans=0; 9 int qx,qy,zx,zy; 10 struct node 11 { 12 int x,y; 13 int time; 14 int k; 15 }; 16 void bfs() 17 { 18 queue<node>q; 19 node p; 20 p.x=qx; 21 p.y=qy; 22 p.time=0; 23 p.k=0; 24 q.push(p); 25 while(!q.empty()) 26 { 27 node p1; 28 p1=q.front(); 29 q.pop(); 30 if(p1.time>=tj) 31 return; 32 if(p1.x==zx&&p1.y==zy) 33 { 34 flag=1; 35 ans=p1.time; 36 break; 37 } 38 39 for(int i=0;i<4;i++) 40 { 41 node p2; 42 p2.x=p1.x+t[i][0]; 43 p2.y=p1.y+t[i][1]; 44 p2.time=p1.time+1; 45 p2.k=p1.k; 46 if(p2.x>=0&&p2.x<n&&p2.y>=0&&p2.y<m&&str[p2.x][p2.y]!='*') 47 { 48 49 if('a'<=str[p2.x][p2.y]&&str[p2.x][p2.y]<='z') 50 { 51 p2.k=p2.k|(1<<(str[p2.x][p2.y]-'a')); 52 if(!vist[p2.x][p2.y][p2.k]) 53 { 54 vist[p2.x][p2.y][p2.k]=1; 55 q.push(p2); 56 } 57 } 58 else 59 if('A'<=str[p2.x][p2.y]&&str[p2.x][p2.y]<='Z') 60 { 61 int k=p2.k&(1<<(str[p2.x][p2.y]-'A')); 62 if(!vist[p2.x][p2.y][p2.k]&&k) 63 { 64 vist[p2.x][p2.y][p2.k]=1; 65 q.push(p2); 66 } 67 } 68 else if(vist[p2.x][p2.y][p2.k]==0) 69 { 70 vist[p2.x][p2.y][p2.k]=1; 71 q.push(p2); 72 } 73 } 74 } 75 } 76 } 77 int main() 78 { 79 while(scanf("%d%d%d",&n,&m,&tj)>0) 80 { 81 for(int i=0;i<n;i++) 82 scanf("%s",str[i]); 83 for(int i=0;i<n;i++) 84 for(int j=0;j<m;j++) 85 { 86 if(str[i][j]=='@') 87 { 88 qx=i; 89 qy=j; 90 } 91 if(str[i][j]=='^') 92 { 93 zx=i; 94 zy=j; 95 } 96 } 97 flag=0; 98 ans=0; 99 memset(vist,0,sizeof(vist)); 100 bfs(); 101 if(flag==0) 102 printf("-1 "); 103 else 104 printf("%d ",ans); 105 } 106 return 0; 107 }