链接:https://ac.nowcoder.com/acm/problem/14572
来源:牛客网
来源:牛客网
题目描述
小明现在在玩一个游戏,游戏来到了教学关卡,迷宫是一个N*M的矩阵。
小明的起点在地图中用“S”来表示,终点用“E”来表示,障碍物用“#”来表示,空地用“.”来表示。
障碍物不能通过。小明如果现在在点(x,y)处,那么下一步只能走到相邻的四个格子中的某一个:(x+1,y),(x-1,y),(x,y+1),(x,y-1);
小明想要知道,现在他能否从起点走到终点。
输入描述:
本题包含多组数据。 每组数据先输入两个数字N,M 接下来N行,每行M个字符,表示地图的状态。 数据范围: 2<=N,M<=500 保证有一个起点S,同时保证有一个终点E.
输出描述:
每组数据输出一行,如果小明能够从起点走到终点,那么输出Yes,否则输出No
思路:这是一道最最基础且经典的迷宫DFS求解是否存在路径的题目
只要打出AC的代码基本可以当成这一类题目的模板使用,只要稍微改一下一些地方就行
代码如下:
#include<stdio.h>
#include<string.h>
int N,M,flag=0;
char mp[520][520]; //存储整个地图
int vis[520][520]; //存储节点对应的状态,未被遍历过为0,已被遍历过为1
int dir[4][2]= {{0,1},{1,0},{0,-1},{-1,0}}; //方向数组,存储四个方向
void DFS(int x,int y) {
for(int i=0; i<4; i++) {
int xx=x+dir[i][0];
int yy=y+dir[i][1];
if(mp[xx][yy]!='#' && vis[xx][yy]==0 && xx>=0 && xx<N && yy>=0 && yy<M) { //如果当前点可以通行
vis[xx][yy]=1; //改变节点状态
if(mp[xx][yy]=='E') { //已经找到了,退出函数
flag=1;
return;
}
DFS(xx,yy); //继续深度搜索
}
}
}
int main() {
int x,y;
while(~scanf("%d %d",&N,&M)) { //注意是多组数据输入
flag=0; //注意flag重新置0
memset(vis,0,sizeof(vis)); //注意清空vis数组
memset(mp,'\0',sizeof(mp));
for(int i=0; i<N; i++) {
scanf("%s",mp[i]);
}
for(int i=0; i<N; i++) {
for(int j=0; j<M; j++) {
if(mp[i][j]=='S') { //记录起点所在下标
x=i;
y=j;
}
}
}
DFS(x,y);
if(flag==0) printf("No\n");
else printf("Yes\n");
}
return 0;
}
#include<string.h>
int N,M,flag=0;
char mp[520][520]; //存储整个地图
int vis[520][520]; //存储节点对应的状态,未被遍历过为0,已被遍历过为1
int dir[4][2]= {{0,1},{1,0},{0,-1},{-1,0}}; //方向数组,存储四个方向
void DFS(int x,int y) {
for(int i=0; i<4; i++) {
int xx=x+dir[i][0];
int yy=y+dir[i][1];
if(mp[xx][yy]!='#' && vis[xx][yy]==0 && xx>=0 && xx<N && yy>=0 && yy<M) { //如果当前点可以通行
vis[xx][yy]=1; //改变节点状态
if(mp[xx][yy]=='E') { //已经找到了,退出函数
flag=1;
return;
}
DFS(xx,yy); //继续深度搜索
}
}
}
int main() {
int x,y;
while(~scanf("%d %d",&N,&M)) { //注意是多组数据输入
flag=0; //注意flag重新置0
memset(vis,0,sizeof(vis)); //注意清空vis数组
memset(mp,'\0',sizeof(mp));
for(int i=0; i<N; i++) {
scanf("%s",mp[i]);
}
for(int i=0; i<N; i++) {
for(int j=0; j<M; j++) {
if(mp[i][j]=='S') { //记录起点所在下标
x=i;
y=j;
}
}
}
DFS(x,y);
if(flag==0) printf("No\n");
else printf("Yes\n");
}
return 0;
}
甚至可以省掉vis数组,代码如下
#include<stdio.h>
#include<string.h>
int N,M,flag=0;
char mp[520][520];
int dir[4][2]= {{0,1},{1,0},{0,-1},{-1,0}};
void DFS(int x,int y) {
for(int i=0; i<4; i++) {
int xx=x+dir[i][0];
int yy=y+dir[i][1];
if(mp[xx][yy]!='#' && xx>=0 && xx<N && yy>=0 && yy<M) {
if(mp[xx][yy]=='E') {
flag=1;
return;
}
mp[xx][yy]='#';
DFS(xx,yy);
}
}
}
int main() {
int x,y;
while(~scanf("%d %d",&N,&M)) {
flag=0;
for(int i=0; i<N; i++) {
scanf("%s",mp[i]);
}
for(int i=0; i<N; i++) {
for(int j=0; j<M; j++) {
if(mp[i][j]=='S') {
x=i;
y=j;
}
}
}
DFS(x,y);
if(flag==0) printf("No\n");
else printf("Yes\n");
}
return 0;
}
#include<string.h>
int N,M,flag=0;
char mp[520][520];
int dir[4][2]= {{0,1},{1,0},{0,-1},{-1,0}};
void DFS(int x,int y) {
for(int i=0; i<4; i++) {
int xx=x+dir[i][0];
int yy=y+dir[i][1];
if(mp[xx][yy]!='#' && xx>=0 && xx<N && yy>=0 && yy<M) {
if(mp[xx][yy]=='E') {
flag=1;
return;
}
mp[xx][yy]='#';
DFS(xx,yy);
}
}
}
int main() {
int x,y;
while(~scanf("%d %d",&N,&M)) {
flag=0;
for(int i=0; i<N; i++) {
scanf("%s",mp[i]);
}
for(int i=0; i<N; i++) {
for(int j=0; j<M; j++) {
if(mp[i][j]=='S') {
x=i;
y=j;
}
}
}
DFS(x,y);
if(flag==0) printf("No\n");
else printf("Yes\n");
}
return 0;
}