这一题就是把每把钥匙记成状态s,用bfs搜索三维dp【i][j][s],i,j表示坐标,s表示已经拿到钥匙的状态,门其实没什么,就是遇到门时看s,在s上这扇门的钥匙如果已经拿到就可以过去,如果没拿到就无法通过,搜索中间只是加了个条件,以下是我的代码,#include<stdio.h> #include<string.h> #include<queue> using namespace std; int n,m,k,p,a[110][110]; int dp[22][22][3000]; char g[110][110]; int dx[110],dy[110]; int dX[110],dY[110]; int ax,ay; char c; int move[4][2]= {{0,1},{0,-1},{1,0},{-1,0}}; struct node { int x,y,s; node(int w,int e,int r) { x=w; y=e; s=r; } }; int bfs() { int i,j,s,nx,ny; queue<node>q; while(!q.empty()) q.pop(); s=0; q.push(node(ax,ay,s)); memset(dp,-1,sizeof(dp)); dp[ax][ay][s]=0; while(!q.empty()) { node tmp=q.front(); q.pop(); if(a[tmp.x][tmp.y]==3)//这是到门口了返回; return dp[tmp.x][tmp.y][tmp.s]; for(i=0; i<4; i++) { nx=tmp.x+move[i][0]; ny=tmp.y+move[i][1]; s=tmp.s; if(nx<0||nx>=n||ny<0||ny>=m) continue; if(a[nx][ny]==-2) continue; if(a[nx][ny]==1)//遇到钥匙 { c=g[nx][ny]; s|=(1<<(c-'a')); if(dp[nx][ny][s]!=-1) continue; dp[nx][ny][s]=dp[tmp.x][tmp.y][tmp.s]+1; q.push(node(nx,ny,s)); continue; } if(a[nx][ny]==2)//遇到门 { c=g[nx][ny]; if((s&(1<<(c-'A')))==0) continue; if(dp[nx][ny][s]!=-1) continue; dp[nx][ny][s]=dp[tmp.x][tmp.y][tmp.s]+1; q.push(node(nx,ny,s)); continue; } if(dp[nx][ny][s]!=-1) continue; dp[nx][ny][s]=dp[tmp.x][tmp.y][tmp.s]+1; q.push(node(nx,ny,s)); } } return -1; } int main() { int i,j,x,y,q; while(scanf("%d%d%d",&n,&m,&q)!=EOF) { for(i=0; i<n; i++) scanf("%s",g[i]); memset(a,-1,sizeof(a)); p=0; k=0; for(i=0; i<n; i++) for(j=0; j<m; j++) { if(g[i][j]=='@') { ax=i; ay=j; } if(g[i][j]=='*') a[i][j]=-2; if(g[i][j]>='a'&&g[i][j]<='z') a[i][j]=1; if(g[i][j]>='A'&&g[i][j]<='Z') a[i][j]=2; if(g[i][j]=='^') a[i][j]=3; } if(bfs()==-1||bfs()>=q) printf("-1\n"); else printf("%d\n",bfs()); } return 0; }
hdu1429 胜利大逃亡(续)bfs状态压缩
最新推荐文章于 2020-02-03 20:25:08 发布