ACwing1112(DFS问题)

一天Extense在森林里探险的时候不小心走入了一个迷宫,迷宫可以看成是由 nnn∗n 的格点组成,每个格点只有2种状态,.#,前者表示可以通行后者表示不能通行。

同时当Extense处在某个格点时,他只能移动到东南西北(或者说上下左右)四个方向之一的相邻格点上,Extense想要从点A走到点B,问在不走出迷宫的情况下能不能办到。

如果起点或者终点有一个不能通行(为#),则看成无法办到。

注意:A、B不一定是两个不同的点。

输入格式

第1行是测试数据的组数 kk,后面跟着 kk 组输入。

每组测试数据的第1行是一个正整数 nn,表示迷宫的规模是 nnn∗n 的。

接下来是一个 nnn∗n 的矩阵,矩阵中的元素为.或者#

再接下来一行是 4 个整数 ha,la,hb,lbha,la,hb,lb,描述 AA 处在第 haha 行, 第 lala 列,BB 处在第 hbhb 行, 第 lblb 列。

注意到 ha,la,hb,lbha,la,hb,lb 全部是从 0 开始计数的。

输出格式

k行,每行输出对应一个输入。

能办到则输出“YES”,否则输出“NO”。

数据范围

1n1001≤n≤100

输入样例:

2
3
.##
..#
#..
0 0 2 2
5
.....
###.#
..#..
###..
...#.
0 0 4 0

输出样例:

YES
NO
 完整代码:
#include<bits/stdc++.h>//头文件,这个很好用
using namespace std;
int n,x1,x2,ya1,ya2,vis[105][105];
char mg;//
bool flag;//
int dx[4][2]={{0,1},{0,-1},{1,0},{-1,0}};//从0
//写DFS
void dfs(int x,int y)
{
  for (int i=0;i<4;i++)//
  {
    int nx=x+dx[i][0];
    int ny=y+dx[i][1];
    if(nx>=0&&nx<n&&ny>=0&&ny<n&&vis[nx][ny]==0)//
    {  
      vis[nx][ny]=1;//
      if(nx==x2&&ny==ya2)
      {
        printf("YES ");
        flag=true;
        break;
      }
      else
        dfs(nx,ny);
    }
  }
}
//
1.注意在写DFS时候,常用模板:返回值为void,传入起点,遍历起点的所有相邻点(不必担心这个起点和终点重合的情况,后面有一个检查的机制在main 函数里面),
2.遍历的时候利用一个for循环+一个方向数组,对于每一个相邻的点都要进行边界检查+新旧检查
3.将此点标记为旧点;
4.判断是否为终点:是->return 不是->继续搜他的相邻点
 
int main()
{
  int N;
  scanf("%d",&N);
  while(N--)//很好解决了检查多组数据
  {
    memset(vis,0,sizeof(vis));
    flag=false;//清零功能
    scanf("%d",&n);
    for (int i=0;i<n;i++)
      for (int j=0;j<n;j++)
      {
        cin>>mg;
        if(mg=='#')
        vis[i][j]=1;
      }//实际上节省了一般DFS需要的map空间(看具体的题目)
    scanf("%d %d",&x1,&ya1);
    scanf("%d %d",&x2,&ya2);
    if (vis[x1][ya1]||vis[x2][ya2])//检车起点与终点重合的情况
    {
      printf("NO ");
      continue;//当起止点重合时,跳出if-else循环
    }
    else
      dfs(x1,ya1);
    if(!flag)//还有一个flag检查机制
    printf("NO ");
    }
    return 0;
}
Tip:
hhh,前几天确实偷懒了,后面补上;
 
 
 
 
 
原文地址:https://www.cnblogs.com/WAsbry/p/12836812.html