HDU 4771 Stealing Harry Potter's Precious

来源:互联网 发布:java连接ssh的jar包 编辑:程序博客网 时间:2024/06/01 23:36

题意是给你一个起点@,.为可走,#为不可走,再给你一些宝藏的坐标,问取完这些宝藏需要的最短距离是多少,如果不能输出-1.

个人认为模拟题最重要的是划分步骤,现在我们来理一理这道题的步骤。

第一步寻找每一个宝藏点到下一个点的最短路,对于每个起点通过bfs实现。

第二步判断路径的先后顺序,这里可以通过dfs,进行2的n次方枚举,数据范围小便可以完成。

这就将一个模拟题拆分为两个子问题,一步一步写便可以完成。

下附AC代码。

#include<iostream>#include<stdio.h>#include<string.h>#include<queue>#define maxn 150using namespace std;struct nod{int x,y;nod(int a,int b){x=a;y=b;}nod(){}}val[maxn];int n,m,qq,cnt;queue<nod> q;int ans=987654321;int valnum[maxn][maxn];int num[maxn][maxn];char gra[maxn][maxn];int vis[maxn][maxn][maxn];int dis[maxn][maxn][maxn];int fx[]={0,1,-1,0,0};int fy[]={0,0,0,1,-1};void bfs(int x,int y,int num){while(!q.empty())q.pop();q.push(nod(x,y));vis[num][x][y]=1;dis[num][x][y]=0;while(!q.empty()){nod now=q.front();q.pop();for(int i=1;i<=4;i++){int nx=now.x+fx[i];int ny=now.y+fy[i];if(1<=nx && nx<=n && 1<=ny && ny<=m && gra[nx][ny]=='.' && vis[num][nx][ny]==0){vis[num][nx][ny]=1;dis[num][nx][ny]=dis[num][now.x][now.y]+1;q.push(nod(nx,ny));}}}}void dfs(int x,int y,int lef[],int now){int flag=true; for(int i=1;i<=qq;i++){if(lef[i]){flag=false;break;}}if(flag==true){ans=min(ans,now);return;}for(int i=1;i<=4;i++)if(lef[i]){int d=dis[valnum[x][y]][val[i].x][val[i].y];if(d!=-1){lef[i]=0;dfs(val[i].x,val[i].y,lef,now+d);lef[i]=1;}}}int main(){while(cin>>n>>m && (n||m)){ans=987654321;memset(vis,0,sizeof(vis));memset(dis,-1,sizeof(dis));cnt=0;int nx,ny;for(int i=1;i<=n;i++)for(int j=1;j<=m;j++){cin>>gra[i][j];cnt++;num[i][j]=cnt;if(gra[i][j]=='@')nx=i,ny=j;}valnum[nx][ny]=0;bfs(nx,ny,0);cin>>qq;for(int i=1;i<=qq;i++){int x,y;cin>>x>>y;val[i].x=x;val[i].y=y;valnum[x][y]=i;bfs(x,y,i);}int temp[5];for(int i=1;i<=4;i++)temp[i]=1;dfs(nx,ny,temp,0);if(ans==987654321)cout<<"-1"<<endl;else cout<<ans<<endl;}}

原创粉丝点击