SP96 SHOP-Shopping 题解

\(To\) \(SP96\)

这是一道比较简单的 \(bfs\) ,初学者可以锻炼一下自己理解题意和改代码的能力。

题目中有几个细节:

  • \(n\)\(m\) 的输入顺序,应该先输入 \(m\) ,再输入 \(n\)
  • 输入时如果用的是 \(scanf\) ,要注意对换行符的处理。
  • \(n=0\) \(m=0\) 时,结束输入。
  • 注意初始化。

一般的 \(bfs\) 则是开一个数组来储存这个点有无访问过,可是这道题,所要求的是最短时间,因此访问过的点不一定是最优路径,因此,应该换一种思路,重开一个数组来储存到达这个点的最短时间

#include<cstdio>
#include<iostream>
#include<queue>
#include<cstring>
using namespace std;
struct node{
	int x;
	int y;
	int time;
};
int n,m;
char mp[5000][5000];
int vis[5000][5000];
queue<node> Q;
int sx,sy,ex,ey;
int dx[4]={0,0,1,-1};
int dy[4]={1,-1,0,0};
int main(){
	while(1){
		scanf("%d%d",&m,&n);//输入的时候注意m和n的顺序
		if(n==0&&m==0){//结束输入
			break;
		}
		memset(mp,0,sizeof(mp));
		memset(vis,0x7,sizeof(vis));
		for(int i=0;i<n;i++){
			for(int j=0;j<m;j++){
				scanf(" %c",&mp[i][j]);//过滤换行符
				if(mp[i][j]=='S'){//储存起点坐标
					sx=i;
					sy=j;
				}
				if(mp[i][j]=='D'){//储存终点坐标
					ex=i;
					ey=j;
				}
			}
		}
		node a,b,c;
		a.x=sx;
		a.y=sy;
		a.time=0;
		Q.push(a);
		while(!Q.empty()){
			b=Q.front();
			Q.pop();
			for(int i=0;i<4;i++){
				c.x=b.x+dx[i];
				c.y=b.y+dy[i];
				if(c.x==ex&&c.y==ey){
					if(vis[ex][ey]>b.time) vis[ex][ey]=b.time;
				}
				if(c.x>=0&&c.x<n&&c.y>=0&&c.y<m&&mp[c.x][c.y]>='1'&&mp[c.x][c.y]<='9'){
					c.time=b.time+(mp[c.x][c.y]-'0');
					if(c.time<vis[c.x][c.y]) vis[c.x][c.y]=c.time;
					else continue;//如果此方案无法更优,则直接废除此方案
					a.x=c.x;
					a.y=c.y;
					a.time=c.time;
					Q.push(a);
				}
			}
		}
		printf("%d\n",vis[ex][ey]);
		while(!Q.empty()){//清空队列
			Q.pop();
		}
	}
	return 0;
}
posted @ 2022-05-15 10:07  Scorilon  阅读(83)  评论(0)    收藏  举报