hdu5025 (2014广州网赛1004)Saving Tang Monk

来源:互联网 发布:程序员有前途吗 编辑:程序博客网 时间:2024/05/01 19:26

        题意:类似走迷宫的一个题,给一个n*n的地图,从K开始走到T,标#号的地方不能走。走的过程中,要按顺序拿m种钥匙(在地图中是数字,每种可能有多把),如果遇到蛇S,需要花1的额外时间把它打死。输出走到终点的最短时间。

        思路:状态空间搜索。如果把钥匙的取得情况和蛇的生存情况也看成状态,就简单多了。状态第一、二维是行和列。钥匙最多9,需要按顺序拿,所以第三维开10就足够了。蛇的生存情况可以用5位二进制表示,也就是第四维开32。然后用优先队列搜。比赛的时候这题A出来真是扬眉吐气~


#include <iostream>               #include <stdio.h>               #include <cmath>               #include <algorithm>               #include <iomanip>               #include <cstdlib>               #include <string>               #include <string.h>               #include <vector>               #include <queue>               #include <stack>               #include <map>             #include <assert.h>    #include <set>             #include <ctype.h>                    #define ll long long           #define max3(a,b,c) max(a,max(b,c))               using namespace std;  char mp[110][110];int a[110][110][10][32];int dn[]={-1,1,0,0};int dm[]={0,0,-1,1};struct node{int nn;int mm;int key;int snk;int dis;node(int a,int b,int c,int d,int ee){nn=a; mm=b; key=c; snk=d; dis=ee;}bool operator<(node b)const{return dis>b.dis;}};int main(){int n,m;while(cin>>n>>m){if(n==0&&m==0)break;memset(a,-1,sizeof(a));int snk=0;int startn;int startm;int endn;int endm;for(int i=1;i<=n;i++){scanf("%s",mp[i]+1);for(int j=1;j<=n;j++){if(mp[i][j]=='K'){startn=i;startm=j;}else if(mp[i][j]=='S'){mp[i][j]=snk+'A';snk++;}else if(mp[i][j]=='T'){endn=i;endm=j;}}}node start(startn,startm,0,0,0); a[startn][startm][0][0]=0;priority_queue<node> que; que.push(start);int ans=0;while(!que.empty()){node cur=que.top(); que.pop();int cn=cur.nn;int cm=cur.mm;int ckey=cur.key;int csnk=cur.snk;int cdis=cur.dis;if(cn==endn&&cm==endm&&ckey==m){ans=cdis;break;}for(int d=0;d<4;d++){int newn=cn+dn[d];int newm=cm+dm[d];if( newn<1||newn>n||newm<1||newm>n )continue;if( mp[newn][newm]=='#' )continue;if( mp[newn][newm]=='.'||mp[newn][newm]=='T'||mp[newn][newm]=='K' ){if(a[newn][newm][ckey][csnk]==-1){a[newn][newm][ckey][csnk]=cdis+1;node nd(newn,newm,ckey,csnk,cdis+1);que.push(nd);}}if( mp[newn][newm]>='A'&&mp[newn][newm]<='E' ){int tmp=mp[newn][newm]-'A';tmp=(1<<tmp);if(tmp&csnk){if(a[newn][newm][ckey][csnk]==-1){a[newn][newm][ckey][csnk]=cdis+1;node nd(newn,newm,ckey,csnk,cdis+1);que.push(nd);}}else{if(a[newn][newm][ckey][csnk|tmp]==-1){a[newn][newm][ckey][csnk|tmp]=cdis+2;node nd(newn,newm,ckey,csnk|tmp,cdis+2);que.push(nd);}}}if( mp[newn][newm]>='1'&&mp[newn][newm]<='9' ){int tmp=mp[newn][newm]-'0';if(tmp==ckey+1){if(a[newn][newm][ckey+1][csnk]==-1){a[newn][newm][ckey+1][csnk]=cdis+1;node nd(newn,newm,ckey+1,csnk,cdis+1);que.push(nd);}}else{if(a[newn][newm][ckey][csnk]==-1){a[newn][newm][ckey][csnk]=cdis+1;node nd(newn,newm,ckey,csnk,cdis+1);que.push(nd);}}}}}if(ans==0){cout<<"impossible"<<endl;}else{cout<<ans<<endl;}}return 0;}


0 0
原创粉丝点击