[编程题 深度优先遍历] 红与黑 (详细注释 易懂)

题目描述:

 题目链接:红与黑__牛客网

 有一间长方形的房子,地上铺了红色、黑色两种颜色的正方形瓷砖。你站在其中一块黑色的瓷砖上,只能向相邻的(上下左右四个方向)黑色瓷砖移动。请写一个程序,计算你总共能够到达多少块黑色的瓷砖。

输入描述:

输入包含多组数据。

每组数据第一行是两个整数 m 和 n(1≤m, n≤20)。紧接着 m 行,每行包括 n 个字符。每个字符表示一块瓷砖的颜色,规则如下:

1. “.”:黑色的瓷砖;
2. “#”:白色的瓷砖;
3. “@”:黑色的瓷砖,并且你站在这块瓷砖上。该字符在每个数据集合中唯一出现一次。

输出描述:

对应每组数据,输出总共能够到达多少块黑色的瓷砖。

题目解读:

    在一个 m 行 n 列 的长方形格子中,铺满了瓷砖,瓷砖有两种颜色 黑色和白色, 你可能在任意位置,从你的起始位置开始,你只能向 上下左右 四个方向前进,并且只有下一个位置是黑色瓷砖,你才能移动到下一个位置,请问你能移动走过多少黑色瓷砖(包括起始位置你所在的瓷砖)。

解题思想:

     题目的输入是 每行一个 n 列的字符串,我们用一个m 行 n 列 的二维字符数组接收,对输入的每个字符串进行遍历,依次将每个字符 放到  二维字符数组中, 同时放完以后,要对这个字符进行比较,如果是 @ ,那说明这个字符所在坐标就是你当前所在位置,记下这个位置的 坐标。 然后将 二维字符数组 ,你所在的坐标 ,以及 m和n 作为参数传给另一个函数,进行深度遍历。 

   在另一个函数中,进行深度遍历的思想是, 首先用一个二维数组记录向每个方向前进的坐标变化值,然后用你所在的位置的 x 和 y 坐标 依次加上左边方向的 x 值和y值(以向左为例),加上之后,你就向左走了一步,我们要做的就是 判断当前位置的 x 和 y 坐标 是否超过边界,如果没有超过边界,并且它是 ' . ' (也就是黑色瓷砖),那说明当前位置符合题意,就给count + 1 ,同时 把这个位置的字符改为' #' (也就是改为 白色瓷砖,避免后面重复遍历), 然后把这个位置作为新的参数 传给本函数,进行递归,它会一直向左遍历(以先向左遍历 为例),当左边遍历完以后,再向 方向函数中的另一个方向遍历,当把最左边的(以先向左遍历 为例)一个黑色瓷砖的 上下左右都遍历完了 ,然后开始回退,再进行次最左瓷砖(以先向上遍历 为例)的上下左边遍历,直到最后遍历完成,返回。 但要注意一个问题,就是 我们一开始所在的位置,它是黑色瓷砖,但是没有被计算在内,所以在返回到主函数后,我们要给它 加1。    

代码注释:

// write your code here
import java.util.*;
public class Main{
    public static void main(String[] args){
        Scanner scan = new Scanner(System.in);
        while(scan.hasNextInt()){
            int m = scan.nextInt();
            int n = scan.nextInt();
            int[][] maps = new int[m][n];
            int x =0;
            int y = 0;
            for(int i=0;i< m;i++){
                String str = scan.next();
                for(int j=0;j<str.length();j++){
         // 将每行输入的字符串进行 字符遍历,放入字符二维数组中
                    maps[i][j] = str.charAt(j);
            // 如果当前字符为 @ ,就记录它的 坐标
                    if(str.charAt(j)=='@'){
                        x = i;
                        y = j ;
                    }
                }
            }
                  // 要给最后返回的结果手动加 1
            System.out.println(blackTiles(maps,x,y,m,n)+1);
        }
    }
    public static int blackTiles(int[][] maps,int x,int y,int m,int n){
        int[][] directions ={{-1,0},{1,0},{0,-1},{0,1}};
        int count =0;
        // 依次遍历 当前位置的四个方向
        for(int i=0;i< 4;i++){
            int nx = x+directions[i][0];
            int ny = y+directions[i][1];
          // 对当前位置的合法性 以及 字符是否为 ' . ' 进行判断
            if(nx >=0 && nx <m && ny >=0 && ny < n && maps[nx][ny]=='.'){
           // 如果当前是黑瓷砖,就改为白瓷砖,避免重复遍历
                maps[nx][ny]='#';
              // 在当前位置处,进行递归
                count +=1+ blackTiles(maps,nx,ny,m,n);
            }
            
        }
        return count;
    }
}

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值