hdu1429 胜利大逃亡(续)???天天逃亡???
作者:互联网
题目链接:http://icpc.njust.edu.cn/Problem/Hdu/1429/
题目就是迷宫问题的变种,给出一张地图,上面分布着钥匙和门,一种要是只能开一种特定的门,给出起点和终点,问在t时间内是否能够走到终点。这个问题显然是要用bfs解决,但是状态量除了位置之外还有钥匙,持有的钥匙不同到达同一个位置也是状态空间中的一种不同的状态,所以用三维记录状态,状态的记录可以用二进制进行状态压缩,毕竟钥匙只有有和无两种状态。
代码如下:
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef unsigned int ui; 4 typedef long long ll; 5 typedef unsigned long long ull; 6 #define pf printf 7 #define mem(a,b) memset(a,b,sizeof(a)) 8 #define prime1 1e9+7 9 #define prime2 1e9+9 10 #define pi 3.14159265 11 #define lson l,mid,rt<<1 12 #define rson mid+1,r,rt<<1|1 13 #define scand(x) scanf("%llf",&x) 14 #define f(i,a,b) for(int i=a;i<=b;i++) 15 #define scan(a) scanf("%d",&a) 16 #define dbg(args) cout<<#args<<":"<<args<<endl; 17 #define inf 0x3f3f3f3f 18 #define maxn 25 19 int n,m,t; 20 char Map[maxn][maxn]; 21 int sx,sy,tx,ty; 22 bool vis[maxn][maxn][(1<<10)];//钥匙最多是2^10-1种状态 23 int dir[][2]={0,1,0,-1,1,0,-1,0}; 24 struct node{ 25 int x,y,step; 26 int key;//钥匙也是一种状态,所以考虑状态压缩存储有限的钥匙的状态 27 node(int x,int y,int s,int key):x(x),y(y),step(s),key(key){} 28 node(){} 29 }; 30 node cur,nxt; 31 int bfs() 32 { 33 queue<node>q;//选择队列这种结构在于队列前面的结点step值小,step是连续变化的值 34 q.push(node(sx,sy,0,0)); 35 vis[sx][sy][0]=1; 36 while(!q.empty()) 37 { 38 cur=q.front(); 39 q.pop(); 40 if(cur.x==tx&&cur.y==ty&&cur.step<t) 41 { 42 return cur.step; 43 } 44 f(i,0,3) 45 { 46 nxt=cur; 47 nxt.x+=dir[i][0]; 48 nxt.y+=dir[i][1]; 49 nxt.step++; 50 if(nxt.x<1||nxt.x>n||nxt.y<1||nxt.y>m||Map[nxt.x][nxt.y]=='*')continue; 51 if(vis[nxt.x][nxt.y][nxt.key])continue;//相对于非门非钥匙的位置,首先判断是否已经入队 52 char c=Map[nxt.x][nxt.y]; 53 if(c>='a'&&c<='j') 54 { 55 nxt.key|=(1<<(c-'a'));//用二进制将状态压缩进每一位中 56 if(vis[nxt.x][nxt.y][nxt.key])continue; 57 } 58 if(c>='A'&&c<='J') 59 { 60 if(!(nxt.key&(1<<(c-'a'))))continue;//遇到门的时候钥匙的状态不会改变,所以不必重复检查状态是否发生变化 61 } 62 vis[nxt.x][nxt.y][nxt.key]=1;//上面筛选掉所有不能入队的状态,剩余的状态都必须进队 63 q.push(nxt); 64 } 65 } 66 return -1; 67 } 68 int main() 69 { 70 //freopen("input.txt","r",stdin); 71 //freopen("output.txt","w",stdout); 72 std::ios::sync_with_stdio(false); 73 while(scanf("%d%d%d",&n,&m,&t)!=EOF) 74 { 75 mem(vis,false); 76 f(i,1,n) 77 f(j,1,m) 78 { 79 scanf(" %c",&Map[i][j]); 80 if(Map[i][j]=='@')sx=i,sy=j; 81 if(Map[i][j]=='^')tx=i,ty=j; 82 } 83 pf("%d\n",bfs()); 84 } 85 }
标签:nxt,hdu1429,cur,逃亡,long,天天,钥匙,&&,define 来源: https://www.cnblogs.com/randy-lo/p/12511804.html