标签:style blog color sp for 数据 div on log
题意:
n*m的迷宫。多多要从(1,1)到达(n,m)。每移动一步消耗1秒。有P种钥匙。
有K个门或墙。给出K个信息:x1,y1,x2,y2,gi 含义是(x1,y1)与(x2,y2)之间有gi。gi=0:墙 1,2,3.... :第1种门,第2种门,第3种门.....
有S把钥匙。给出S个信息:x1,y1,qi 含义是位置(x1,y1)上有一把第qi种的钥匙。
问多多最少花多少秒到达(n,m)。若无法到达输出-1。
数据范围:
(1<= n, m <=50, 0<= p <=10).
(0<= k <=500)
(0<= S <=50)
思路:
n,m很小。经典BFS+状压,
注意的是,同一位置上可能有多把钥匙。(注意到S的范围是S<=50)
还有一个要注意:位运算式子的处理要仔细。(最好测试一下)。
代码:
struct node{ int x,s; node(int _x,int _s){ x=_x, s=_s; } }; int n,m,p,k,S; int xx1,yy1,xx2,yy2,gi; int mazeG[55][55][55][55], mazeK[55][55][15]; int dp[55][55][1050]; int bfs(){ queue<node> q; mem(dp,-1); int s=0; rep(i,1,p) if(mazeK[1][1][i]>0) s|=(1<<(i-1)); q.push(node(101,s)); dp[1][1][s]=0; if(1==n && 1==m) return 0; while(!q.empty()){ node f=q.front(); q.pop(); rep(i,0,3){ int nx=f.x/100+uu[i], ny=f.x%100+vv[i]; int _s=f.s; if(nx<=0||ny<=0||nx>n||ny>m||(mazeG[f.x/100][f.x%100][nx][ny]==0)) continue; //overBound or meet the wall. if(mazeG[f.x/100][f.x%100][nx][ny]>0){ int yes=_s&(1<<(mazeG[f.x/100][f.x%100][nx][ny]-1)); if(yes==0) continue; //have corresponding key. } int ns=_s; rep(i,1,p) if(mazeK[nx][ny][i]) ns|=(1<<(i-1)); if(dp[nx][ny][ns]!=-1) continue; q.push(node(nx*100+ny,ns)); dp[nx][ny][ns]=dp[f.x/100][f.x%100][_s]+1; if(nx==n&&ny==m) return dp[nx][ny][ns]; } } return -1; } int main(){ while(scanf("%d%d%d",&n,&m,&p)!=EOF){ //p kinds of doors scanf("%d",&k); mem(mazeG,-1); //doors or walls mem(mazeK,false); //keys rep(i,1,k){ scanf("%d%d%d%d%d",&xx1,&yy1,&xx2,&yy2,&gi); mazeG[xx1][yy1][xx2][yy2]=gi; mazeG[xx2][yy2][xx1][yy1]=gi; } scanf("%d",&S); // S keys rep(i,1,S){ scanf("%d%d%d",&xx1,&yy1,&gi); mazeK[xx1][yy1][gi]=true; } printf("%d\n",bfs()); } }
标签:style blog color sp for 数据 div on log
原文地址:http://www.cnblogs.com/fish7/p/4085896.html