洛谷——AT1350 深さ優先探索

题目描述

この問題は、講座用問題です。ページ下部に解説が掲載されています。

高橋君の住む街は長方形の形をしており、格子状の区画に区切られています。 長方形の各辺は東西及び南北に並行です。 各区画は道または塀のどちらかであり、高橋君は道を東西南北に移動できますが斜めには移動できません。 また、塀の区画は通ることができません。

高橋君が、塀を壊したりすることなく道を通って魚屋にたどり着けるかどうか判定してください。

输入格式

入力は以下の形式で標準入力から与えられる。


 $ H $   $ W $ 
 $ c_{0,0} $   $ c_{0,1} $   $ c_{0,W-1} $ 
 $ c_{1,0} $   $ c_{1,1} $   $ c_{1,W-1} $ 
:
 $ c_{H-1,0} $   $ c_{H-1,1} $   $ c_{H-1,W-1} $ 
  • 1 行目には、街の南北の長さとして整数 H(1≦H≦500) H(1≦H≦500) と東西の長さとして整数 W(1≦W≦500) W(1≦W≦500) が空白で区切られて与えられる。
  • 2 行目からの H H 行には、格子状の街の各区画における状態 c_{i,j}(0≦i≦H-1,\ 0≦j≦W-1) ci,j
    ​ (0≦i≦H−1, 0≦j≦W−1) が与えられる。
  • i 行目 j 文字目の文字 ci,j ​はそれぞれ s, g, ., #のいずれかで与えられ、座標 (j,i) (j,i) が下記のような状態であることを表す。
  • s: その区画が家であることを表す。
  • g: その区画が魚屋であることを表す。
  • .: その区画が道であることを表す。
  • #: その区画が塀であることを表す。
  • 高橋君は家・魚屋・道は通ることができるが、塀は通ることができない。
  • 与えられた街の外を通ることはできない。
  • sgはそれぞれ 1 つずつ与えられる。

输出格式

塀を 1 回も壊さずに、家から魚屋まで辿り着くことができる場合は Yes、辿りつけない場合は Noを標準出力に 1 行で出力せよ。

题意翻译

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

现在给出地图:
s:代表高桥先生的家

g:代表鱼店

.:代表道路

#:代表墙壁

高桥先生不能穿过墙壁。

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

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

输入输出样例

输入 #1

4 5
s####
....#
#####
#...g

输出 #1

No

输入 #2

4 4
...s
....
....
.g..

输出 #2

Yes

输入 #3

10 10
s.........
#########.
#.......#.
#..####.#.
##....#.#.
#####.#.#.
g.#.#.#.#.
#.#.#.#.#.
###.#.#.#.
#.....#...

输出 #3

No

输入 #4

10 10
s.........
#########.
#.......#.
#..####.#.
##....#.#.
#####.#.#.
g.#.#.#.#.
#.#.#.#.#.
#.#.#.#.#.
#.....#...

输出 #4

Yes

输入 #5

1 10
s..####..g

输出 #5

No

思路

这题是个很简单的DFS模板题,然而我还是受苦了(哭)。
注意的地方:
1.起点不一定是左上角,而是s所在的位置;
2.判断能不能走,直接判断是不是墙壁#即可,其他三种情况都能走,包括遇到下一个s
3.输出要换行;
4.开的二维数组要大一点;
5.二维数组的行和列都是从0开始的,而不是1(我在这里卡了很久)。
另外,可以精简代码的地方:
1.用两个dx和dy的数组来模拟移动,可以少写很多if语句,直接将四种情况放在一个for循环里即可;
2.是否越界可以写成一个bool型的判断函数。

代码

#include<cstdio>
#include<cctype>
#include<stdlib.h>
#include<algorithm>
#include<string>
#include<string.h>
#include<utility>
#include<vector>
#include<iostream>
using namespace std;
const int maxn = 510;
bool visited[maxn][maxn];
char maze[maxn][maxn];
void dfs(int now_x, int now_y, int n, int m, bool &flag){
	visited[now_x][now_y] = true;
	if(maze[now_x][now_y]=='g'){
		flag = true;
		return;
	}
	if(maze[now_x-1][now_y]!='#' && visited[now_x-1][now_y]==false && now_x-1>=0 && now_x-1<n && now_y>=0 && now_y<m){
		dfs(now_x-1, now_y, n, m, flag);
	}
	if(maze[now_x+1][now_y]!='#' && visited[now_x+1][now_y]==false && now_x+1>=0 && now_x+1<n && now_y>=0 && now_y<m){
		dfs(now_x+1, now_y, n, m, flag);
	}
	if(maze[now_x][now_y-1]!='#' && visited[now_x][now_y-1]==false && now_x>=0 && now_x<n && now_y-1>=0 && now_y-1<m){
		dfs(now_x, now_y-1, n, m, flag);
	}
	if(maze[now_x][now_y+1]!='#' && visited[now_x][now_y+1]==false && now_x>=0 && now_x<n && now_y+1>=0 && now_y+1<m){
		dfs(now_x, now_y+1, n, m, flag);
	}
}
int main()
{
	int n, m;
	scanf("%d%d", &n, &m);
	int start_x, start_y;
	for(int i=0;i<n;i++){
		getchar();
		for(int j=0;j<m;j++){
			scanf("%c", &maze[i][j]);
			if(maze[i][j]=='s'){
				start_x = i;
				start_y = j;
			}
		}
	}
	bool flag = false;
	dfs(start_x, start_y, n, m, flag);
	if(flag==true) printf("Yes\n");
	else printf("No\n");
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值