洛谷AT1350 深さ優先探索

题目传送门

题意翻译

高桥先生住的小区是长方形的,被划分成一个个格子。高桥先生想从家里去鱼店,高桥先生每次可以走到他前后左右四个格子中的其中一个,但不能斜着走,也不能走出小区。

现在给出地图:

s:代表高桥先生的家

g:代表鱼店

.:代表道路

#:代表墙壁

高桥先生不能穿过墙壁。

输入:第一行输入n(1<=n<=500),m(1<=m<=500)代表小区的长和宽,接下来n行每行m个字符,描述小区中的每个格子。

输出:如果高桥先生能到达鱼店,输出"Yes",否则输出"No"。

思路:用dfs或bfs都行,思路如下所示:

dfs:

#include<bits/stdc++.h>
using namespace std;
int n,m;//小区的长、宽
char a[510][510];//小区的情况
bool f[510][510],flag=false;//可不可以通行、可不可以到达鱼店
void dfs(int x,int y) {
	if(flag) return ;//如果之前找到了就不用再找了
	if(x>n||x<1||y>m||y<1||!f[x][y]) return ;//超过小区的范围或者是墙壁
	if(a[x][y]=='g') {//找到了
		flag=true;//打上标记
		return ;
	}
	f[x][y]=false;//走过的就不用再走了
	dfs(x+1,y);//搜索下一个目标
	dfs(x,y+1);
	dfs(x-1,y);
	dfs(x,y-1);
}
int main() {
	cin>>n>>m;
	memset(f,false,sizeof(f));//不能走出小区
	int x,y;
	for(int i=1; i<=n; i++)
		for(int j=1; j<=m; j++) {
			cin>>a[i][j];
			if(a[i][j]=='.'||a[i][j]=='g') f[i][j]=true;
			if(a[i][j]=='s') f[i][j]=true,x=i,y=j;//记下坐标
		}
	dfs(x,y);
	if(flag) cout<<"Yes"<<endl;//能走到
	else cout<<"No"<<endl;

	return 0;
}

bfs:

#include<bits/stdc++.h>
using namespace std;
int n,m,ans,q[1000010][2],zx[4]= {1,-1,0,0},zy[4]= {0,0,1,-1};
char a[510][510];
bool f[510][510];
int bfs(int x,int y) {//注意因为bfs不像dfs那样循环,所以可以直接返回
	ans++;
	f[x][y]=false;
	int head=1,tail;
	q[++tail][0]=x,q[tail][1]=y;
	while(head<=tail) {
		for(int i=0; i<4; i++) {
			int dx=q[head][0]+zx[i],dy=q[head][1]+zy[i];
			if(f[dx][dy]) {
				if(a[dx][dy]=='g')
					return 1;
				f[dx][dy]=false;
				q[++tail][0]=dx,q[tail][1]=dy;
			}
		}
		head++;
	}
	return 0;//找不到
}
int main() {
	cin>>n>>m;
	memset(f,false,sizeof(f));
	int x,y;
	for(int i=1; i<=n; i++)
		for(int j=1; j<=m; j++) {
			cin>>a[i][j];
			if(a[i][j]=='.'||a[i][j]=='g') f[i][j]=true;
			if(a[i][j]=='s') f[i][j]=true,x=i,y=j;
		}
	if(bfs(x,y)) cout<<"Yes"<<endl;
	else cout<<"No"<<endl;

	return 0;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值