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);
}
}
}