代碼隨想錄算法訓練營第五十二天 |101. 孤島的總面積102. 沉沒孤島103. 水流問題104.建造最大島嶼

101. 孤島的總面積

卡碼網:101. 孤島的總面積(opens new window)

題目描述

給定一個由 1(陸地)和 0(水)組成的矩陣,島嶼指的是由水平或垂直方向上相鄰的陸地單元格組成的區域,且完全被水域單元格包圍。孤島是那些位于矩陣內部、所有單元格都不接觸邊緣的島嶼。

現在你需要計算所有孤島的總面積,島嶼面積的計算方式為組成島嶼的陸地的總數。

輸入描述

第一行包含兩個整數 N, M,表示矩陣的行數和列數。之后 N 行,每行包含 M 個數字,數字為 1 或者 0。

輸出描述

輸出一個整數,表示所有孤島的總面積,如果不存在孤島,則輸出 0。

輸入示例

4 5
1 1 0 0 0
1 1 0 0 0
0 0 1 0 0
0 0 0 1 1

輸出示例:

1

提示信息:

在矩陣中心部分的島嶼,因為沒有任何一個單元格接觸到矩陣邊緣,所以該島嶼屬于孤島,總面積為 1。

數據范圍:

1 <= M, N <= 50。

本題使用dfs,bfs,并查集都是可以的。

本題要求找到不靠邊的陸地面積,那么我們只要從周邊找到陸地然后 通過 dfs或者bfs 將周邊靠陸地且相鄰的陸地都變成海洋,然后再去重新遍歷地圖 統計此時還剩下的陸地就可以了。

如圖,在遍歷地圖周圍四個邊,靠地圖四邊的陸地,都為綠色,

在遇到地圖周邊陸地的時候,將1都變為0,此時地圖為這樣:

import java.util.*;public class Main {private static int count = 0;private static final int[][] dir = {{0, 1}, {1, 0}, {-1, 0}, {0, -1}}; // 四個方向private static void bfs(int[][] grid, int x, int y) {Queue<int[]> que = new LinkedList<>();que.add(new int[]{x, y});grid[x][y] = 0; // 只要加入隊列,立刻標記count++;while (!que.isEmpty()) {int[] cur = que.poll();int curx = cur[0];int cury = cur[1];for (int i = 0; i < 4; i++) {int nextx = curx + dir[i][0];int nexty = cury + dir[i][1];if (nextx < 0 || nextx >= grid.length || nexty < 0 || nexty >= grid[0].length) continue; // 越界了,直接跳過if (grid[nextx][nexty] == 1) {que.add(new int[]{nextx, nexty});count++;grid[nextx][nexty] = 0; // 只要加入隊列立刻標記}}}}public static void main(String[] args) {Scanner scanner = new Scanner(System.in);int n = scanner.nextInt();int m = scanner.nextInt();int[][] grid = new int[n][m];// 讀取網格for (int i = 0; i < n; i++) {for (int j = 0; j < m; j++) {grid[i][j] = scanner.nextInt();}}// 從左側邊,和右側邊向中間遍歷for (int i = 0; i < n; i++) {if (grid[i][0] == 1) bfs(grid, i, 0);if (grid[i][m - 1] == 1) bfs(grid, i, m - 1);}// 從上邊和下邊向中間遍歷for (int j = 0; j < m; j++) {if (grid[0][j] == 1) bfs(grid, 0, j);if (grid[n - 1][j] == 1) bfs(grid, n - 1, j);}count = 0;for (int i = 0; i < n; i++) {for (int j = 0; j < m; j++) {if (grid[i][j] == 1) bfs(grid, i, j);}}System.out.println(count);}
}

?

102. 沉沒孤島

卡碼網題目鏈接(ACM模式)(opens new window)

題目描述:

給定一個由 1(陸地)和 0(水)組成的矩陣,島嶼指的是由水平或垂直方向上相鄰的陸地單元格組成的區域,且完全被水域單元格包圍。孤島是那些位于矩陣內部、所有單元格都不接觸邊緣的島嶼。

現在你需要將所有孤島“沉沒”,即將孤島中的所有陸地單元格(1)轉變為水域單元格(0)。

輸入描述:

第一行包含兩個整數 N, M,表示矩陣的行數和列數。

之后 N 行,每行包含 M 個數字,數字為 1 或者 0,表示島嶼的單元格。

輸出描述

輸出將孤島“沉沒”之后的島嶼矩陣。

輸入示例:

4 5
1 1 0 0 0
1 1 0 0 0
0 0 1 0 0
0 0 0 1 1

輸出示例:

1 1 0 0 0
1 1 0 0 0
0 0 0 0 0
0 0 0 1 1

提示信息:

將孤島沉沒:

數據范圍:

1 <= M, N <= 50

步驟一:深搜或者廣搜將地圖周邊的 1 (陸地)全部改成 2 (特殊標記)

步驟二:將水域中間 1 (陸地)全部改成 水域(0)

步驟三:將之前標記的 2 改為 1 (陸地)

如圖:

?

import java.util.Scanner;public class Main {static int[][] dir = { {-1, 0}, {0, -1}, {1, 0}, {0, 1} }; // 保存四個方向public static void dfs(int[][] grid, int x, int y) {grid[x][y] = 2;for (int[] d : dir) {int nextX = x + d[0];int nextY = y + d[1];// 超過邊界if (nextX < 0 || nextX >= grid.length || nextY < 0 || nextY >= grid[0].length) continue;// 不符合條件,不繼續遍歷if (grid[nextX][nextY] == 0 || grid[nextX][nextY] == 2) continue;dfs(grid, nextX, nextY);}}public static void main(String[] args) {Scanner scanner = new Scanner(System.in);int n = scanner.nextInt();int m = scanner.nextInt();int[][] grid = new int[n][m];for (int i = 0; i < n; i++) {for (int j = 0; j < m; j++) {grid[i][j] = scanner.nextInt();}}// 步驟一:// 從左側邊,和右側邊 向中間遍歷for (int i = 0; i < n; i++) {if (grid[i][0] == 1) dfs(grid, i, 0);if (grid[i][m - 1] == 1) dfs(grid, i, m - 1);}// 從上邊和下邊 向中間遍歷for (int j = 0; j < m; j++) {if (grid[0][j] == 1) dfs(grid, 0, j);if (grid[n - 1][j] == 1) dfs(grid, n - 1, j);}// 步驟二、步驟三for (int i = 0; i < n; i++) {for (int j = 0; j < m; j++) {if (grid[i][j] == 1) grid[i][j] = 0;if (grid[i][j] == 2) grid[i][j] = 1;}}for (int i = 0; i < n; i++) {for (int j = 0; j < m; j++) {System.out.print(grid[i][j] + " ");}System.out.println();}scanner.close();}
}

103. 水流問題

卡碼網題目鏈接(ACM模式)(opens new window)

題目描述:

現有一個 N × M 的矩陣,每個單元格包含一個數值,這個數值代表該位置的相對高度。矩陣的左邊界和上邊界被認為是第一組邊界,而矩陣的右邊界和下邊界被視為第二組邊界。

矩陣模擬了一個地形,當雨水落在上面時,水會根據地形的傾斜向低處流動,但只能從較高或等高的地點流向較低或等高并且相鄰(上下左右方向)的地點。我們的目標是確定那些單元格,從這些單元格出發的水可以達到第一組邊界和第二組邊界。

輸入描述:

第一行包含兩個整數 N 和 M,分別表示矩陣的行數和列數。

后續 N 行,每行包含 M 個整數,表示矩陣中的每個單元格的高度。

輸出描述:

輸出共有多行,每行輸出兩個整數,用一個空格隔開,表示可達第一組邊界和第二組邊界的單元格的坐標,輸出順序任意。

輸入示例:

5 5
1 3 1 2 4
1 2 1 3 2
2 4 7 2 1
4 5 6 1 1
1 4 1 2 1

1
2
3
4
5
6

輸出示例:

0 4
1 3
2 2
3 0
3 1
3 2
4 0
4 1

1
2
3
4
5
6
7
8

提示信息:

圖中的藍色方塊上的雨水既能流向第一組邊界,也能流向第二組邊界。所以最終答案為所有藍色方塊的坐標。

數據范圍:

1 <= M, N <= 50

?

public class Main {// 采用 DFS 進行搜索public static void dfs(int[][] heights, int x, int y, boolean[][] visited, int preH) {// 遇到邊界或者訪問過的點,直接返回if (x < 0 || x >= heights.length || y < 0 || y >= heights[0].length || visited[x][y]) return;// 不滿足水流入條件的直接返回if (heights[x][y] < preH) return;// 滿足條件,設置為true,表示可以從邊界到達此位置visited[x][y] = true;// 向下一層繼續搜索dfs(heights, x + 1, y, visited, heights[x][y]);dfs(heights, x - 1, y, visited, heights[x][y]);dfs(heights, x, y + 1, visited, heights[x][y]);dfs(heights, x, y - 1, visited, heights[x][y]);}public static void main(String[] args) {Scanner sc = new Scanner(System.in);int m = sc.nextInt();int n = sc.nextInt();int[][] heights = new int[m][n];for (int i = 0; i < m; i++) {for (int j = 0; j < n; j++) {heights[i][j] = sc.nextInt();}}// 初始化兩個二位boolean數組,代表兩個邊界boolean[][] pacific = new boolean[m][n];boolean[][] atlantic = new boolean[m][n];// 從左右邊界出發進行DFSfor (int i = 0; i < m; i++) {dfs(heights, i, 0, pacific, Integer.MIN_VALUE);dfs(heights, i, n - 1, atlantic, Integer.MIN_VALUE);}// 從上下邊界出發進行DFSfor (int j = 0; j < n; j++) {dfs(heights, 0, j, pacific, Integer.MIN_VALUE);dfs(heights, m - 1, j, atlantic, Integer.MIN_VALUE);}// 當兩個邊界二維數組在某個位置都為true時,符合題目要求List<List<Integer>> res = new ArrayList<>();for (int i = 0; i < m; i++) {for (int j = 0; j < n; j++) {if (pacific[i][j] && atlantic[i][j]) {res.add(Arrays.asList(i, j));}}}// 打印結果for (List<Integer> list : res) {for (int k = 0; k < list.size(); k++) {if (k == 0) {System.out.print(list.get(k) + " ");} else {System.out.print(list.get(k));}}System.out.println();}}
}

104.建造最大島嶼

卡碼網題目鏈接(ACM模式)(opens new window)

題目描述:

給定一個由 1(陸地)和 0(水)組成的矩陣,你最多可以將矩陣中的一格水變為一塊陸地,在執行了此操作之后,矩陣中最大的島嶼面積是多少。

島嶼面積的計算方式為組成島嶼的陸地的總數。島嶼是被水包圍,并且通過水平方向或垂直方向上相鄰的陸地連接而成的。你可以假設矩陣外均被水包圍。

輸入描述:

第一行包含兩個整數 N, M,表示矩陣的行數和列數。之后 N 行,每行包含 M 個數字,數字為 1 或者 0,表示島嶼的單元格。

輸出描述:

輸出一個整數,表示最大的島嶼面積。

輸入示例:

4 5
1 1 0 0 0
1 1 0 0 0
0 0 1 0 0
0 0 0 1 1

1
2
3
4
5

輸出示例

6

提示信息

對于上面的案例,有兩個位置可將 0 變成 1,使得島嶼的面積最大,即 6。

數據范圍:

1 <= M, N <= 50。

其實每次深搜遍歷計算最大島嶼面積,我們都做了很多重復的工作。

只要用一次深搜把每個島嶼的面積記錄下來就好。

第一步:一次遍歷地圖,得出各個島嶼的面積,并做編號記錄。可以使用map記錄,key為島嶼編號,value為島嶼面積

第二步:再遍歷地圖,遍歷0的方格(因為要將0變成1),并統計該1(由0變成的1)周邊島嶼面積,將其相鄰面積相加在一起,遍歷所有 0 之后,就可以得出 選一個0變成1 之后的最大面積。

拿如下地圖的島嶼情況來舉例: (1為陸地)

第一步,則遍歷地圖,并將島嶼的編號和面積都統計好,過程如圖所示:

public class Main {// 該方法采用 DFS// 定義全局變量// 記錄每次每個島嶼的面積static int count;// 對每個島嶼進行標記static int mark;// 定義二維數組表示四個方位static int[][] dirs = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};// DFS 進行搜索,將每個島嶼標記為不同的數字public static void dfs(int[][] grid, int x, int y, boolean[][] visited) {// 當遇到邊界,直接returnif (x < 0 || x >= grid.length || y < 0 || y >= grid[0].length) return;// 遇到已經訪問過的或者遇到海水,直接返回if (visited[x][y] || grid[x][y] == 0) return;visited[x][y] = true;count++;grid[x][y] = mark;// 繼續向下層搜索dfs(grid, x, y + 1, visited);dfs(grid, x, y - 1, visited);dfs(grid, x + 1, y, visited);dfs(grid, x - 1, y, visited);}public static void main (String[] args) {// 接收輸入Scanner sc = new Scanner(System.in);int m = sc.nextInt();int n = sc.nextInt();int[][] grid = new int[m][n];for (int i = 0; i < m; i++) {for (int j = 0; j < n; j++) {grid[i][j] = sc.nextInt();}}// 初始化mark變量,從2開始(區別于0水,1島嶼)mark = 2;// 定義二位boolean數組記錄該位置是否被訪問boolean[][] visited = new boolean[m][n];// 定義一個HashMap,記錄某片島嶼的標記號和面積HashMap<Integer, Integer> getSize = new HashMap<>();// 定義一個HashSet,用來判斷某一位置水四周是否存在不同標記編號的島嶼HashSet<Integer> set = new HashSet<>();// 定義一個boolean變量,看看DFS之后,是否全是島嶼boolean isAllIsland = true;// 遍歷二維數組進行DFS搜索,標記每片島嶼的編號,記錄對應的面積for (int i = 0; i < m; i++) {for (int j = 0; j < n; j++) {if (grid[i][j] == 0) isAllIsland = false;if (grid[i][j] == 1) {count = 0;dfs(grid, i, j, visited);getSize.put(mark, count);mark++;}}}int result = 0;if (isAllIsland) result =  m * n;// 對標記完的grid繼續遍歷,判斷每個水位置四周是否有島嶼,并記錄下四周不同相鄰島嶼面積之和// 每次計算完一個水位置周圍可能存在的島嶼面積之和,更新下result變量for (int i = 0; i < m; i++) {for (int j = 0; j < n; j++) {if (grid[i][j] == 0) {set.clear();// 當前水位置變更為島嶼,所以初始化為1int curSize = 1;for (int[] dir : dirs) {int curRow = i + dir[0];int curCol = j + dir[1];if (curRow < 0 || curRow >= m || curCol < 0 || curCol >= n) continue;int curMark = grid[curRow][curCol];// 如果當前相鄰的島嶼已經遍歷過或者HashMap中不存在這個編號,繼續搜索if (set.contains(curMark) || !getSize.containsKey(curMark)) continue;set.add(curMark);curSize += getSize.get(curMark);}result = Math.max(result, curSize);}}}// 打印結果System.out.println(result);}
}

?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/898483.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/898483.shtml
英文地址,請注明出處:http://en.pswp.cn/news/898483.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Simple-BEV的bilinear_sample 作為view_transformer的解析,核心是3D-2D關聯點生成

文件路徑models/view_transformers 父類 是class BiLinearSample(nn.Module)基于https://github.com/aharley/simple_bev。 函數解析 函數bev_coord_to_feature_coord的功能 將鳥瞰圖3D坐標通過多相機&#xff08;針孔/魚眼&#xff09;內外參投影到圖像特征平面&#xff0…

A/B測試入門指南

目錄 一、什么是A/B測試1.1 A/A測試1.2 多變量測試 二、A/B測試應用場景三、A/B測試基本流程四、A/B測試面試真題4.1 【是什么】4.2 【為什么】4.3 【怎么做】 五、應用實戰 一、什么是A/B測試 A/B 測試是一種常見的實驗方法&#xff0c;用于比較兩個或多個方案的效果&#xff…

自己構建的交叉編譯器找不到PATH_MAX

接上篇centos6.10 編譯gcc11.5 x64到aarch64交叉工具鏈 -CSDN博客 PATH_MAX找不到&#xff0c;不僅在編譯gcc的過程中遇到&#xff0c;而且臨時改gcc源碼添加#define PATH_MAX 4096 宏定義后勉強通過gcc全量編譯。這個新的gcc編譯使用了PATH_MAX宏的代碼還是會找不到。這個問題…

vscode查看文件歷史git commit記錄

方案一&#xff1a;GitLens 在vscode擴展商店下載GitLens 選中要查看的文件&#xff0c;vscode界面右上角點擊GitLens的圖標&#xff0c;選擇Toggle File Blame 界面顯示當前打開文件的所有修改歷史記錄 鼠標放到某條記錄上&#xff0c;可以看到記錄詳情&#xff0c;選中O…

ngx_http_conf_ctx_t

定義在 src/http/ngx_http_config.h typedef struct {void **main_conf;void **srv_conf;void **loc_conf; } ngx_http_conf_ctx_t; ngx_http_conf_ctx_t 是 Nginx 中用于管理 HTTP 配置上下文的核心結構體&#xff0c;其設計體現了 Nginx 多級配置&…

IREE AI編譯器編譯測試流程指南

iree onnx demo 計劃協議系列博客,記錄學習iree編譯器的過程. 今天第一篇博客,記錄安裝和測試iree 文章目錄 iree onnx demo下載安裝ireepython環境安裝編譯測試1. [前端] onnx模型轉MLIR文件2. [后端] MLIR文件轉可執行文件3. [執行] 執行測試編譯后的文件 關于后端設備的介…

【產品小白】如何運營一個新的產品

運營一個新產品既充滿機遇&#xff0c;也伴隨著挑戰。新產品運營的核心在于快速獲取用戶、驗證市場假設、持續迭代與優化&#xff0c;并通過有效的推廣和用戶反饋機制不斷完善產品。 1. 市場調研與定位 用戶調研&#xff1a;在產品初期&#xff0c;通過訪談、問卷、競品分析等…

破解驗證碼新利器:基于百度OCR與captcha-killer-modified插件的免費調用教程

破解驗證碼新利器&#xff1a;基于百度OCR與captcha-killer-modified插件的免費調用教程 引言 免責聲明&#xff1a; 本文提供的信息僅供參考&#xff0c;不承擔因操作產生的任何損失。讀者需自行判斷內容適用性&#xff0c;并遵守法律法規。作者不鼓勵非法行為&#xff0c;保…

JSON 解析中需要清理的危險字符

在代碼中 replace(chr(0), "") 的作用是刪除 JSON 響應中可能存在的空字符&#xff08;Null character&#xff09;。以下是詳細解釋&#xff1a; 1. chr(0) 是什么&#xff1f; chr(0) 表示 ASCII 碼為 0 的字符&#xff0c;即空字符&#xff08;Null Character&am…

指令系統2(Load/Store 指令)

一. Load/Store 指令 1. 前變址 前變址指令是在讀取或存儲數據時&#xff0c;先根據基址寄存器&#xff08;Rn&#xff09;與偏移量&#xff08;offset&#xff09;計算出有效地址&#xff0c;再進行數據操作。相關指令及示例如下&#xff1a; LDR R0, [R1, #4]&#xff1a;從…

ubuntu部署運行xinference全精度對話deepseek本地部署圖文教程

前置環境搭建勞請移步往期 source activate 自己環境名啟動python3.12環境安裝xinference&#xff0c; 按教程敲命令&#xff0c;wheel包與wsl的通用&#xff0c;pip install 包名。 vllm引擎&#xff0c;transform引擎也會順帶自動裝上了。 后續操作請參照往期教程。本地部署模…

技術分享 | MySQL內存使用率高問題排查

本文為墨天輪數據庫管理服務團隊第51期技術分享&#xff0c;內容原創&#xff0c;如需轉載請聯系小墨&#xff08;VX&#xff1a;modb666&#xff09;并注明來源。 一、問題現象 問題實例mysql進程實際內存使用率過高 二、問題排查 2.1 參數檢查 mysql版本 &#xff1a;8.0.…

[AI速讀]混合語言IP集成:挑戰與高效解決方案

在現代SoC(系統級芯片)設計中,IP(知識產權模塊)復用是提升開發效率的關鍵。然而,當設計涉及多種硬件描述語言(如SystemVerilog、VHDL、SystemC)時,如何高效集成不同語言的IP模塊成為一大難題。本文將從實際設計場景出發,探討混合語言IP集成的核心挑戰,并介紹一套方法…

【vulhub/wordpress靶場】------獲取webshell

1.進入靶場環境&#xff1a; 輸入&#xff1a;cd / vulhub / wordpress / pwnscriptum 修改版本號&#xff1a; vim docker-compose.yml version: 3 保存退出 開啟靶場環境&#xff1a; docker - compose up - d 開啟成功&#xff0c;docker ps查看端口 靶場環境80…

微信小程序:用戶拒絕小程序獲取當前位置后的處理辦法

【1】問題描述&#xff1a; 小程序在調用 wx.getLocation() 獲取用地理位置時&#xff0c;如果用戶選擇拒絕授權&#xff0c;代碼會直接拋出錯誤。如果再次調用 wx.getLocation() 時&#xff0c;就不會在彈窗詢問用戶是否允許授權。導致用戶想要重新允許獲取地理位置時&#x…

NLP 與常見的nlp應用

自然語言處理&#xff08;NLP&#xff09;是一個廣泛的領域&#xff0c;它不僅包括自然語言理解&#xff08;NLU&#xff09;&#xff0c;還涉及一系列其他任務和子領域。以下是NLP領域中的主要組成部分及其相關任務&#xff1a; 1. 自然語言理解&#xff08;NLU&#xff09; …

全網首創/純Qt/C++實現國標GB28181服務/實時視頻/云臺控制/預置位/錄像回放和下載/事件訂閱/語音對講

一、前言說明 用純Qt來實現這個GB28181的想法很久了&#xff0c;具體可以追溯到2014年&#xff0c;一晃十年都過去了&#xff0c;總算是整體的框架和邏輯都打通了&#xff0c;總歸還是雜七雜八的事情多&#xff0c;無法靜下心來研究具體的協議&#xff0c;最開始初步了解協議后…

Django+celery+flower

Djangoceleryflower Django的定時任務及可視化監控Django Django的定時任務及可視化監控 Django的定時任務&#xff0c;以及可視化監控。 Django Django&#xff1b; 首先在python中新建虛擬環境并激活 pip install virtualenv python -m venv venv source venv/bin/activa…

Python 編程題 第十一節:選擇排序、插入排序、刪除字符、目標移動、尾部的0

選擇排序 假定第一個為最小的為已排序序列&#xff0c;與后面的比較&#xff0c;找到未排序序列中最小的后&#xff0c;交換位置&#xff0c;獲得最小元素&#xff0c;依次往后 lst[1,14,25,31,21,13,6,8,14,9,7] def selection_sort(lst):for i in range(len(lst)):min_inde…

組態王Kingview配置為OPCUA服務器的一些問題處理

一、問題描述 1、組態王【運行配置】界面沒有【服務配置】的選項&#xff0c;無法將組態王Kingview配置為OPCUA服務器&#xff1b; 2、點擊組態王【運行配置界面】的【服務配置】選項彈窗警告提示【試圖執行的操作不受支持】&#xff0c;如下圖所示&#xff1a; 二、問題分析 …