Title:
Victory Escape (continued)
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 8573 Accepted Submission(s): 3076
This time, the devil learned the lesson of the last time, and locked Ignatius in an n*m dungeon. Locked doors were installed in some parts of the dungeon, and keys were hidden in other parts of the dungeon. Ignatius was initially locked in (sx,sy) and left the dungeon door in (ex,ey) position. Ignatius can only move from one coordinate to one of the four adjacent coordinates every minute. The Devil King visits the dungeon every t minute. If Ignatius is not in his place, he is taken back. After several attempts, Ignatius has mapped the whole dungeon. Now let's ask you to help him figure out if he can escape again. As long as the devil goes to the exit before his next visit, he will leave the dungeon. If the devil comes back to the exit or has not reached the exit, he will fail to escape.
Represent the road
* Representative Wall
@ Represents the starting position of Ignatius
^ On behalf of Dungeon exports
A-J stands for the door with a lock, and the corresponding keys are a-j, respectively.
A-J represents the key, and the corresponding doors are A-J.
There is a blank line between each set of test data.
4 5 17 @A.B. a*.*. *..*^ c..b* 4 5 16 @A.B. a*.*. *..*^ c..b*
16 -1
Statistic | Submit | Discuss | Note Ideas:
Since it is state compression, let's talk about state compression here.
There are A ~ J doors, a ~ J keys and endpoints on the question. We mark them in binary form.
There are ten bits from a to j, so we need ten binary bits.
Target: a. b. c. d. e. f. g. h. i. j
Number 0: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
Bit number: 1 2 3 4 5 7 8 9 10
By changing the 0 and 1 of each bit, we mark the possibility of the key I currently have, that is, state compression, and use vis[x][y][key] to represent the current state at x,y points. When encountering an iron door, first use | operation to determine whether the value of key 1 < (map [x] [y] -'A') is the same as the original key value. If the same means that the current key can open the door, you can continue to walk, otherwise you can not walk the door, because there is no key.
If you encounter a key, update the value of the key, and then mark the current status as 1, a normal search can be carried out, see the comments specifically.
(For bit operations, look at the key words of Sogou Encyclopedia: bit operations)
Code:
#include <cstdio> #include <cstring> #include <cctype> #include <string> #include <set> #include <iostream> #include <stack> #include <queue> #include <vector> #include <algorithm> #define mem(a,b) memset(a,b,sizeof(a)) #define inf 0x3f3f3f3f #define mod 10000007 #define debug() puts("what the fuck!!!") #define N 1001000 #define M 1000000 #define ll long long using namespace std; int n,m,ans,t,sx,sy,ex,ey; char map[25][25]; int vis[25][25][(1<<10)+20];//Recording state with binary bits int go[4][2]= {0,1,0,-1,1,0,-1,0}; struct node { int x,y,step; int key; }; int bfs(int x,int y) { node now,to; now.x=x,now.y=y,now.step=0,now.key=0; vis[x][y][0]=1; queue<node>q; q.push(now); while(!q.empty()) { now=q.front(); q.pop(); if(now.x==ex&&now.y==ey&&now.step<t) return now.step; for(int i=0; i<4; i++) { to.x=now.x+go[i][0]; to.y=now.y+go[i][1]; to.step=now.step+1; to.key=now.key; if(to.x>=0&&to.x<n&&to.y>=0&&to.y<m&&map[to.x][to.y]!='*'&&!vis[to.x][to.y][to.key]) { if(map[to.x][to.y]>='A'&&map[to.x][to.y]<='J') { int key=to.key|(1<<(map[to.x][to.y]-'A'));//See if it will affect the binary number of the corresponding location, so as to determine whether there is a key to open the door or not. if(key!=to.key)//The impact proves that there is no key, so go straight to the next level of circulation continue; } if(map[to.x][to.y]>='a'&&map[to.x][to.y]<='j') { to.key=to.key|(1<<(map[to.x][to.y]-'a'));//Absorb the current key } vis[to.x][to.y][to.key]=1; q.push(to); } } } return -1; } int main() { while(~scanf("%d%d%d",&n,&m,&t)) { mem(map,0); mem(vis,0); for(int i=0; i<n; i++) { scanf("%s",map[i]); for(int j=0; j<m; j++) { if(map[i][j]=='@')//Find the coordinates of the starting point { sx=i; sy=j; } if(map[i][j]=='^')//Find the coordinates of the end point { ex=i; ey=j; } } } printf("%d\n",bfs(sx,sy)); } return 0; }