题意:N*M的地图,@是起点,#不能走,去拿k个宝藏,求最短步数。
思路:状态空间搜索。前两维是横纵坐标,第三维是宝藏的取得情况,爆搜过去就好了。
#include <stdio.h>
#include <queue>
#include <memory.h>
using namespace std;
#define INF 1000000000
char mp[110][110];
int vis[110][110][16];
struct node{
int nn;int mm;int s;
node(int a,int b,int c){
nn=a;mm=b;s=c;
}
};
int dirn[]={-1,1,0,0};
int dirm[]={0,0,-1,1};
int main(){
int n,m;
while(~scanf("%d%d",&n,&m)){
if(n==0&&m==0)break;
memset(mp,0,sizeof(mp));
int startn,startm;
for(int i=1;i<=n;i++){
scanf("%s",mp[i]+1);
for(int j=1;j<=m;j++){
for(int l=0;l<16;l++)vis[i][j][l]=INF;
if(mp[i][j]=='@'){
startn=i; startm=j;
}
}
}
int k;
scanf("%d",&k);
for(int i=1;i<=k;i++){
int nn,mm;
scanf("%d%d",&nn,&mm);
mp[nn][mm]=i;
}
queue<node> que;
node start(startn,startm,0);
que.push(start);
int ans=INF;
int target=(1<<k)-1;
vis[startn][startm][0]=0;
while(!que.empty()){
node cur=que.front(); que.pop();
int curn=cur.nn;
int curm=cur.mm;
int curs=cur.s;
for(int i=0;i<4;i++){
int newn=curn+dirn[i];
int newm=curm+dirm[i];
int news=curs;
if(mp[newn][newm]==0||mp[newn][newm]=='#')continue;
if(mp[newn][newm]<=4){
news=curs| ( 1<<(mp[newn][newm]-1));
}
if(vis[curn][curm][curs]+1<vis[newn][newm][news]){
node nd(newn,newm,news);
vis[newn][newm][news]=vis[curn][curm][curs]+1;
que.push(nd);
if(news==target)ans=min(ans,vis[curn][curm][curs]+1);
}
}
}
if(ans==INF){
printf("-1\n");
}else{
printf("%d\n",ans);
}
}
return 0;
}
本文介绍了一种用于解决N×M地图中从起点出发,寻找特定数量宝藏的最短路径问题的方法。通过状态空间搜索,算法遍历地图,考虑宝藏收集情况,最终求得最短步数。

被折叠的 条评论
为什么被折叠?



