题目大意:
在一个迷宫中,从起点走到终点,还有几个宝物,问在给定的时间内,到达终点后所能获取的最大价值。(为了结果最大可以来回走)
先用BFS求出入口、各宝物堆、出口两两间的最短距离,然后用DFS利用BFS求出的两两最短距离(保证耗时最小)求出在时间L内到达出口且取得最大价值宝物堆的路径。
#include <iostream> #include <cstring> #include <cstdio> #include <algorithm> #include <queue> using namespace std; char map[55][55]; int a[55][55]; int visit1[55][55]; int visit2[55]; int time[55][55]; int val[55]; int dir[4][2]={-1,0,1,0,0,-1,0,1}; int ans; int sum; int n,m,l,w; struct p { int x,y; }; queue < p >q; void bfs(int x,int y,int e) { int i,j,k,xx,yy; while(q.empty()==0) { q.pop(); } p o; o.x=x; o.y=y; q.push(o); visit1[x][y]=1; time[x][y]=0; while(q.empty()==0) { o=q.front(); q.pop(); for(i=0;i<4;i++) { xx=o.x+dir[i][0]; yy=o.y+dir[i][1]; if(xx>=0&&xx<m&&yy>=0&&yy<n) { if(visit1[xx][yy]==0&&map[xx][yy]!='*') { visit1[xx][yy]=1; time[xx][yy]=time[o.x][o.y]+1; if(map[xx][yy]=='@') { a[e][0]=time[xx][yy]; } if(map[xx][yy]=='<') { a[e][w+1]=time[xx][yy]; } if(isalpha(map[xx][yy])) { a[e][map[xx][yy]-64]=time[xx][yy]; } p nn; nn.x=xx; nn.y=yy; q.push(nn); } } } } } void dfs(int e,int s,int time) { int i,j,k; if(time>l||ans==sum) return ; if(e>w&&s>ans) ans=s; for(i=0;i<w+2;i++) { if(visit2[i]==0&&a[e][i]) { visit2[i]=1; dfs(i,s+val[i],time+a[e][i]); visit2[i]=0; } } } int main() { int i,j,k; int t; cin>>t; int oo=0; while(t--) { oo++; memset(visit1,0,sizeof(visit1)); memset(visit2,0,sizeof(visit2)); memset(a,0,sizeof(a)); sum=0; ans=-1; cin>>n>>m>>l>>w; for(i=1;i<=w;i++) { cin>>val[i]; sum+=val[i]; } val[0]=val[w+1]=0; for(i=0;i<m;i++) { cin>>map[i]; } for(i=0;i<m;i++) { for(j=0;j<n;j++) { memset(visit1,0,sizeof(visit1)); memset(time,0,sizeof(time)); if(map[i][j]=='@') { bfs(i,j,0); // printf("%d %d %d\n",a[0][1],a[0][2],a[1][2]); } else if(map[i][j]=='<') bfs(i,j,w+1); else if(isalpha(map[i][j])) bfs(i,j,map[i][j]-64); } } visit2[0]=1; dfs(0,0,0); cout<<"Case "<<oo<<":"<<endl; if(ans>=0) printf("The best score is %d.\n",ans); else printf("Impossible\n"); if(t) cout<<endl; } return 0; }