dfs题目以及解决思路(Java)

1.题目

最大的蛋糕块(求最大的连通块)
这一天蒜头君生日,他的朋友们一起来给蒜头君买一个大的蛋糕过生日。游戏做完后到了切蛋糕的时刻了,朋友们知道蒜头君喜欢吃蛋糕,便让蒜头军自己给自己切一块最大的。蒜头军看朋友们这么热情也就不客气了。
这块蛋糕是由R × C的网格构成,每个网格上面都放有不同的水果。蒜头君把这些水果分为两类,一类是自己喜欢吃的水果,用==‘#‘来表示;一类是自己不喜欢吃的水果,用’.’==来表示
蒜头君对切除的蛋糕有如下要求:

  • 切除的蛋糕连成一块(可以不为矩阵,在网格上连通)
  • 切除的蛋糕只包含自己喜欢吃的水果

请问,蒜头君最大可以吃到多大的蛋糕?
输入格式
第一行输入两个被空格隔开的整数
R(1≤R≤1000)和C(1≤C≤10000)。
输出格式
输出一个整数,表示蒜头君可以吃到的蛋糕最大是多少(即对应到网络中的格子数)。

样例输入

5 6
.#…
…#…
…#…#
…##.
.#…

样例输出

2

思路分析

即求最大的连通块(所包含的格子数最多)

代码实现

import java.util.Scanner;

/*
测试数据:
输入:
5 6
.#....
..#...
..#..#
...##.
.#....
输入:
2
*/
/**
 * @author Kino
 * @create 2022-08-29 19:41
 */
public class ACM_dfs {

//    static int n; // 行
//    static int m; // 列
//    static boolean[][] v;
    static int[][] t = {{1,0},{-1,0},{0,1},{0,-1}};
    static int cnt=0; // 记录当前连通图的格子数
    static int ans=0; // 记录最大的连通格子数

    public static void main(String[] args) {
        // 1.输出相关值
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt(); // 行
        int m = sc.nextInt(); // 列
        char[][] g = new char[n][];
//        v = new boolean[n][m];

        for (int i = 0; i < n; i++) {
            g[i] = sc.next().toCharArray();
        }
        // 深度优先遍历,寻找最大连通块
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                if (g[i][j] == '#') {
                    cnt = 0;
                    dfs(i,j,g);
                    ans = Math.max(cnt, ans);
                }
            }
        }
        System.out.println(ans);
    }

    private static void dfs(int x, int y, char[][] g) {
        // 1.不合法情况
        if (x < 0 || x >= g.length || y < 0 || y >= g[0].length || g[x][y] == '.') {
            return;
        }
        // 2.将当前访问过的格子设置为:
        g[x][y] = '.';
        // 3.记录当前合法的格子数
        cnt++;
        // 4.继续遍历下一个连通格子
        for (int i = 0; i < 4; i++) {
            int xx = x + t[i][0];
            int yy = y + t[i][1];
            dfs(xx,yy,g);
        }
    }
}

1.题目

在这里插入图片描述在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

思路分析

代码实现

import java.util.HashMap;
import java.util.PriorityQueue;
import java.util.Scanner;

/*
r:1 b:2 g:3 p:5
3 3 3
rbr
rrp
bgg
*/
/**
 * @author Kino
 * @create 2022-08-29 19:18
 */
public class Main {


    static int index = 1;
    static int[][] dir = new int[][]{{-1,0},{1,0},{0,-1},{0,1}};
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int m = sc.nextInt();
        int k = sc.nextInt();
        char[][] matrix = new char[n][];
        for (int i = 0; i < n; i++) {
            matrix[i] = sc.next().toCharArray();
        }
        // 创建flag的目的是:找出所有连通的地方
        int[][] flag = new int[n][m];
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                if (flag[i][j] != 0) continue;
                dfs(matrix,flag, i,j);
                index++;
            }
        }
        // score:存放分数
        HashMap<Character, Integer> score = new HashMap<>();
        score.put('r',1);
        score.put('b',2);
        score.put('g',3);
        score.put('p',5);
        // map:遍历flag数组,存取连通长度和得分   K:代表连通部分长度 V:代表对应的得分
        HashMap<Integer, int[]> map = new HashMap<>();
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                if (!map.containsKey(flag[i][j])) { // 当不包含的时候进入
                    map.put(flag[i][j], new int[]{0,0});
                }
                map.put(flag[i][j], new int[]{map.get(flag[i][j])[0]+1,score.get(matrix[i][j])});
            }
        }
        // 将得分由大到小排序
        // 此处用到了λ表达式
        PriorityQueue<Integer> que = new PriorityQueue<>((o1, o2) -> {
            return o2 - o1;
        });
        for (Integer key : map.keySet()) {
            que.add(map.get(key)[0] * map.get(key)[1]);
        }
        int sum = 0;
        for (int i = 0; i < k; i++) {
            sum += que.poll();
        }
        System.out.println(sum);
    }

    private static void dfs(char[][] matrix, int[][] flag, int row, int col) {
        if (flag[row][col] != 0) return;
        flag[row][col] = index;
        for (int i = 0; i < 4; i++) {
            int nx = row + dir[i][0];
            int ny = col + dir[i][1];
            if (nx < 0 || nx >= matrix.length || ny < 0 || ny >= matrix.length) {
                continue;
            }
            if (matrix[nx][ny] != matrix[row][col]) continue;
            dfs(matrix,flag,nx,ny);
        }

    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值