【备战秋招】每日一题:研发岗-第二题-又一个连通块数数题

news/2024/11/9 2:20:10/

在线评测链接:P1147

前言

​ 第一题太水了,群友已经忘记内容了。想必应该也是个人均都会的签到题。大家从第二题开始看吧

题目内容

塔子哥是一个年轻的程序员,他热爱计算机科学和数学。他一直在思考如何利用计算机技术来解决实际问题。有一天,他接到了一项任务,要为一个遥远的星球上的一座城市设计一个城市规划系统。

这个城市非常大,由许多小区域组成。每个小区域都有一个 n ∗ m n * m nm 的矩阵,矩阵中的每个位置都取值为 W W W R R R,分别代表白色和红色。这些小区域之间可能存在道路或其他障碍物,但每个小区域内部都是连通的。

塔子哥想知道,如果将任意位置 ( i , j ) (i,j) (i,j) 涂成白色后,会有多少个全红的连通块,求一个 n ∗ m n*m nm 的矩阵 a n s ans ans a n s [ i ] [ j ] ans[i][j] ans[i][j] 表示将位置 ( i , j ) (i,j) (i,j) 涂成白色以后,剩下的全红连通块个数。 保证数据随机生成

输入描述

第一行为两个整数 n n n m m m ,( 1 ≤ n , m ≤ 40 1\le n,m \le 40 1n,m40

接下来 n n n 行,每行有 m m m 个字母,每个字母取值为 W W W R R R

输出描述

输出为一个 n ∗ m n*m nm 的矩阵。

样例

输入

4 3
R W W
W R R
R R R
W W W

输出

1 2 2 
2 2 2 
2 3 2 
2 2 2 

思路:bfs/dfs/并查集求联通块个数

非常经典的题。枚举所有点,把它改成白色,然后求一遍联通块个数。

复杂度: O ( n m ∗ n m ) = O ( n 2 m 2 ) O(nm * nm)=O(n^2m^2) O(nmnm)=O(n2m2)

拓展: n , m = 1 e 3 n,m=1e3 n,m=1e3 如何做?

1.学习割点:割点和桥 - Oi Wiki

2.原题来自:D.Router Mesh - 2020 ICPC小米选拔赛第一场

类似题目推荐

LeetCode

剑指 Offer II 105. 岛屿的最大面积

200. 岛屿数量

547. 朋友圈

CodeFun2000

P1094. 米哈游 2023.03.19-第一题-塔子哥的RBG矩阵

P1237 2023.04.15-美团实习-第三题-交通规划

代码

C++

#include <bits/stdc++.h>
using namespace std;const int maxn = 45, dirs[4][2]{-1, 0, 1, 0, 0, -1, 0, 1};
char colors[maxn][maxn];
bool vis[maxn][maxn];
int n, m;
void dfs(int x, int y) {vis[x][y] = true;for (auto &[dx, dy] : dirs) {int nx = x + dx, ny = y + dy;if (nx >= 0 && nx < n && ny >= 0 && ny < m && !vis[nx][ny] && colors[nx][ny] == 'R') {dfs(nx, ny);}}
}// 求联通分量个数
int solve() {memset(vis, 0, sizeof(vis));int cnt = 0;for (int i = 0; i < n; ++i) {for (int j = 0; j < m; ++j) {if (vis[i][j] || colors[i][j] == 'W') continue;dfs(i, j);cnt++;}}return cnt;
}int main() {cin >> n >> m;for (int i = 0; i < n; ++i) {for (int j = 0; j < m; ++j) {cin >> colors[i][j];}}for (int i = 0; i < n; ++i) {for (int j = 0; j < m; ++j) {char preColor = colors[i][j];colors[i][j] = 'W';int cnt = solve();printf("%d ", cnt);colors[i][j] = preColor;}printf("\n");}return 0;
}
// by yhy

python

dfs解法

n , m = list(map(int , input().split()))
a = []
for i in range(n):a.append(list(map(str , input().split())))
dx = [0 , 0 , -1 , 1]
dy = [-1 , 1 , 0 , 0]
bk = set()
# dfs 求联通块个数
def dfs (x , y):bk.add(f"{x} {y}")for i in range (4):nx = x + dx[i]ny = y + dy[i]if nx < 0 or nx >= n or ny < 0 or ny >= m or f"{nx} {ny}" in bk or a[nx][ny] == 'W':continuedfs(nx , ny)
def calc (x , y):bk.clear()t = a[x][y]a[x][y] = 'W'cnt = 0for i in range (n):for j in range (m):if f"{i} {j}" in bk or a[i][j] == 'W':continuedfs(i , j)cnt += 1a[x][y] = treturn cntfor i in range (n):for j in range (m):print (calc(i , j) , end = "")if j == m - 1:print()else:print(" " , end = "")

Java

并查集解法

import java.util.*;public class Main {static int[][] dirs = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}}; // 上下左右四个方向static int[] father; // 并查集数组static int countRedBlocks; // 红色连通块个数public static void main(String[] args) {Scanner scanner = new Scanner(System.in);int n = scanner.nextInt();int m = scanner.nextInt();scanner.nextLine(); // 读取换行符char[][] matrix = new char[n][m];for (int i = 0; i < n; i++) {matrix[i] = scanner.nextLine().replaceAll(" ", "").toCharArray();}int[][] ans = new int[n][m];for (int i = 0; i < n; i++) {for (int j = 0; j < m; j++) {if (matrix[i][j] == 'R') {// 将颜色为 W 的格子修改为 Rmatrix[i][j] = 'W';// 统计剩余的红色连通块个数ans[i][j] = countRedBlocks(matrix, n, m);// 将颜色再改回来,以便下一次统计matrix[i][j] = 'R';} else {ans[i][j] = countRedBlocks(matrix, n, m);}}}// 输出结果for (int i = 0; i < n; i++) {for (int j = 0; j < m; j++) {System.out.print(ans[i][j] + " ");}System.out.println();}}// 计算红色连通块个数private static int countRedBlocks(char[][] matrix, int n, int m) {// 初始化并查集father = new int[n * m];countRedBlocks = 0;for (int i = 0; i < n * m; i++) {father[i] = i;if (matrix[i / m][i % m] == 'R') {countRedBlocks++;}}// 合并相邻格子中的红色连通块for (int i = 0; i < n * m; i++) {int x1 = i / m;int y1 = i % m;if (matrix[x1][y1] == 'R') {for (int[] dir : dirs) {int x2 = x1 + dir[0];int y2 = y1 + dir[1];if (x2 >= 0 && x2 < n && y2 >= 0 && y2 < m && matrix[x2][y2] == 'R') {int p1 = find(i);int p2 = find(x2 * m + y2);if (p1 != p2) {father[p1] = p2;countRedBlocks--;}}}}}return countRedBlocks;}// 查找节点的根节点,并进行路径压缩优化private static int find(int u) {if (u != father[u]) {father[u] = find(father[u]);}return father[u];}
}

Go

package mainimport ("bufio""fmt""os"
)var dx = []int{0, 0, -1, 1}
var dy = []int{-1 , 1 , 0 , 0}
var bk = make(map[string]bool)
var a [][]string
var n, m int
// dfs求联通块
func dfs(x, y int) {bk[fmt.Sprintf("%d %d", x, y)] = truefor i := 0; i < 4; i++ {nx := x + dx[i]ny := y + dy[i]if nx < 0 || nx >= n || ny < 0 || ny >= m || bk[fmt.Sprintf("%d %d", nx, ny)] || a[nx][ny] == "W" {continue}dfs(nx, ny)}
}
// 将这个点涂白,求解连通分量个数
func calc(x, y int) int {bk = make(map[string]bool)t := a[x][y]a[x][y] = "W"cnt := 0for i := 0; i < n; i++ {for j := 0; j < m; j++ {if bk[fmt.Sprintf("%d %d", i, j)] || a[i][j]  == "W" {continue}dfs(i, j)cnt++}}a[x][y] = treturn cnt
}
func main() {reader := bufio.NewReader(os.Stdin)fmt.Scanf("%d %d\n", &n, &m)a = make([][]string, n)for i := 0; i < n; i++ {a[i] = make([]string, m)line, _ := reader.ReadString('\n')for j := 0; j < m; j++ {fmt.Sscanf(string(line[j*2:j*2+1]), "%s", &a[i][j])}}for i := 0; i < n; i++ {for j := 0; j < m; j++ {fmt.Printf("%d", calc(i, j))if j == m-1 {fmt.Println()} else {fmt.Print(" ")}}}
}

Js

let input = "";
process.stdin.resume();
process.stdin.setEncoding("utf-8");process.stdin.on("data", (data) => {input += data;
});process.stdin.on("end", () => {const lines = input.trim().split("\n");const [n, m] = lines[0].trim().split(" ").map(Number);const a = [];for (let i = 1; i <= n; i++) {const row = lines[i].trim().split(" ");a.push(row);}// dfs 求联通块个数const dx = [0, 0, -1, 1];const dy = [-1, 1, 0, 0];const bk = new Set();function dfs(x, y) {bk.add(`${x} ${y}`);for (let i = 0; i < 4; i++) {const nx = x + dx[i];const ny = y + dy[i];if (nx < 0 || nx >= n || ny < 0 || ny >= m || bk.has(`${nx} ${ny}`) || a[nx][ny] === "W") {continue;}dfs(nx, ny);}}// 将[x,y] 涂成白色 ,求连通分量个数function calc(x, y) {bk.clear();const t = a[x][y];a[x][y] = "W";let cnt = 0;for (let i = 0; i < n; i++) {for (let j = 0; j < m; j++) {if (bk.has(`${i} ${j}`) || a[i][j] === "W") {continue;}dfs(i, j);cnt++;}}a[x][y] = t;return cnt;}for (let i = 0; i < n; i++) {let rowOutput = "";for (let j = 0; j < m; j++) {rowOutput += calc(i, j);if (j === m - 1) {rowOutput += "\n";} else {rowOutput += " ";}}process.stdout.write(rowOutput);}
});

http://www.ppmy.cn/news/514767.html

相关文章

有三个线程,分别只能打印A,B和C要求按顺序打印ABC,打印10次(多种方法,小白也懂)

目录 第一种方法:使用LockSupport的park和unpark功能(推荐) 第二种方式:synchronizedwaitnotify 第三种:暴力循环方法(不推荐) 第一种方法:使用LockSupport的park和unpark功能(推荐) 简单来说我们有一个名为LockSupport的方法 park就是阻塞当前进程 unpark就是取消阻塞让其…

【Vuejs】1720- 详细聊一聊 Vue3 动态组件

&#x1f449; 「相关文章」 深入浅出 Vue3 自定义指令6 个你必须明白 Vue3 的 ref 和 reactive 问题初中级前端必须掌握的 10 个 Vue 优化技巧分享 15 个 Vue3 全家桶开发的避坑经验 动态组件[1]是 Vue3 中非常重要的一个组件类型&#xff0c;它可以让我们在不同的场景下灵活地…

各种品牌的Andr​​oid智能手机在Aliexpress.comstore833807

各种品牌的Andr​​oid智能手机在Aliexpress.comstore833807   三星Galaxy S3的   的Andr​​oid 4.3更新发布   如果你拥有三星Galaxy S3的国际版&#xff0c;你就是幸运的。而Android 4.3更新终于开始推出的前旗舰产品。   具体而言&#xff0c;银河S3手机有型号GT-I…

android备份卡刷包,Android 4.3 卡刷版的Root包

Android 4.3恐怕要成为历史上最悲剧的操作系统了&#xff0c;因为它还没有正式发布的时候就被Root了。 日前&#xff0c;网上泄露出原生版Galaxy S4所使用的Android 4.3 ROM&#xff0c;经网友实测之后发现搭载骁龙600处理器的美版Galaxy S4(GT-I9505)可以完美运行这一ROM&…

linux 编译指cpu内核,Linux 有问必答:如何知道进程运行在哪个 CPU 内核上?

问题&#xff1a;我有个 Linux 进程运行在多核处理器系统上。怎样才能找出哪个 CPU 内核正在运行该进程&#xff1f; 当你在 多核 NUMA 处理器上运 行需要较高性能的 HPC(高性能计算)程序或非常消耗网络资源的程序时&#xff0c;CPU/memory 的亲和力是限度其发挥最大性能的重要…

抢班夺权成新跳水王 三星S5周爆跌近2k

三星今年的首款旗舰手机GALAXY S5如期而至&#xff0c;相比上一代的GALAXY S4&#xff0c;正面外观变化不大&#xff0c;后盖采用类皮革质地的塑料材质&#xff0c;配置上搭载高通骁龙800处理器&#xff0c;最高主频2.5GHz&#xff0c;运行内存2GB&#xff0c;机身存储空间为16…

i9500android操作系统跑流量,三星I9500刷机包 百度云ROM54公测版 因为专注 所以精进...

三星Galaxy S4是三星电子在2013年推出的一款手机&#xff0c;搭载的是Exynos 5410双四核处理器&#xff0c;支持ARM的big.LITTLE Processing省电技术&#xff0c;是A7A15的组合(基于Cortex-A15架构&#xff0c;主频1.6GHz、基于Cortex-A7架构&#xff0c;主频1.2GHz。 GPU为Ima…

webpakc原理之开发一个清除console.log(xxx)的loader

一、webpack中清除console的方法 当然想要清除console我们可以使用babel-loader结合babel-plugin-transform-remove-console插件来实现。 安装babel-loader和babel-plugin-transform-remove-console插件 npm install babel-loader babel-plugin-transform-remove-console -D…