Merge branch 'master' of github.com:youngyangyang04/leetcode-master
This commit is contained in:
@@ -388,3 +388,85 @@ if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
```
|
||||
### C
|
||||
|
||||
前缀和
|
||||
```c
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
int n = 0, m = 0, ret_ver = 0, ret_hor = 0;
|
||||
|
||||
// 读取行和列的值
|
||||
scanf("%d%d", &n, &m);
|
||||
// 动态分配数组a(横)和b(纵)的空间
|
||||
int *a = (int *)malloc(sizeof(int) * n);
|
||||
int *b = (int *)malloc(sizeof(int) * m);
|
||||
|
||||
// 初始化数组a和b
|
||||
for (int i = 0; i < n; i++)
|
||||
{
|
||||
a[i] = 0;
|
||||
}
|
||||
for (int i = 0; i < m; i++)
|
||||
{
|
||||
b[i] = 0;
|
||||
}
|
||||
|
||||
// 读取区块权值并计算每行和每列的总权值
|
||||
for (int i = 0; i < n; i++)
|
||||
{
|
||||
for (int j = 0; j < m; j++)
|
||||
{
|
||||
int tmp;
|
||||
scanf("%d", &tmp);
|
||||
a[i] += tmp;
|
||||
b[j] += tmp;
|
||||
}
|
||||
}
|
||||
|
||||
// 计算每列以及每行的前缀和
|
||||
for (int i = 1; i < n; i++)
|
||||
{
|
||||
a[i] += a[i - 1];
|
||||
}
|
||||
for (int i = 1; i < m; i++)
|
||||
{
|
||||
b[i] += b[i - 1];
|
||||
}
|
||||
|
||||
// 初始化ret_ver和ret_hor为最大可能值
|
||||
ret_hor = a[n - 1];
|
||||
ret_ver = b[m - 1];
|
||||
|
||||
// 计算按行划分的最小差异
|
||||
int ret2 = 0;
|
||||
while (ret2 < n)
|
||||
{
|
||||
ret_hor = (ret_hor > abs(a[n - 1] - 2 * a[ret2])) ? abs(a[n - 1] - 2 * a[ret2]) : ret_hor;
|
||||
// 原理同列,但更高级
|
||||
ret2++;
|
||||
}
|
||||
// 计算按列划分的最小差异
|
||||
int ret1 = 0;
|
||||
while (ret1 < m)
|
||||
{
|
||||
if (ret_ver > abs(b[m - 1] - 2 * b[ret1]))
|
||||
{
|
||||
ret_ver = abs(b[m - 1] - 2 * b[ret1]);
|
||||
}
|
||||
ret1++;
|
||||
}
|
||||
|
||||
// 输出最小差异
|
||||
printf("%d\n", (ret_ver <= ret_hor) ? ret_ver : ret_hor);
|
||||
|
||||
// 释放分配的内存
|
||||
free(a);
|
||||
free(b);
|
||||
return 0;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
@@ -562,4 +562,145 @@ if __name__ == "__main__":
|
||||
### Dart
|
||||
|
||||
### C
|
||||
并查集方法一
|
||||
```c
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
// 定义边结构体,包含两个顶点vex1和vex2以及它们之间的权重val
|
||||
struct Edge
|
||||
{
|
||||
int vex1, vex2, val;
|
||||
};
|
||||
|
||||
// 冒泡排序函数,用于按边的权重val不减序排序边数组
|
||||
void bubblesort(struct Edge *a, int numsize)
|
||||
{
|
||||
for (int i = 0; i < numsize - 1; ++i)
|
||||
{
|
||||
|
||||
for (int j = 0; j < numsize - i - 1; ++j)
|
||||
{
|
||||
if (a[j].val > a[j + 1].val)
|
||||
{
|
||||
struct Edge temp = a[j];
|
||||
a[j] = a[j + 1];
|
||||
a[j + 1] = temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
int v, e;
|
||||
int v1, v2, val;
|
||||
int ret = 0;
|
||||
|
||||
scanf("%d%d", &v, &e);
|
||||
struct Edge *edg = (struct Edge *)malloc(sizeof(struct Edge) * e);
|
||||
int *conne_gra = (int *)malloc(sizeof(int) * (v + 1));
|
||||
|
||||
// 初始化连通图数组,每个顶点初始时只与自己相连通
|
||||
for (int i = 0; i <= v; ++i)
|
||||
{
|
||||
conne_gra[i] = i;
|
||||
}
|
||||
|
||||
// 读取所有边的信息并存储到edg(存储所有边的)数组中
|
||||
for (int i = 0; i < e; ++i)
|
||||
{
|
||||
scanf("%d%d%d", &v1, &v2, &val);
|
||||
edg[i].vex1 = v1;
|
||||
edg[i].vex2 = v2;
|
||||
edg[i].val = val;
|
||||
}
|
||||
bubblesort(edg, e); // 调用冒泡排序函数对边进行排序
|
||||
|
||||
// 遍历所有边,执行Kruskal算法来找到最小生成树
|
||||
for (int i = 0; i < e; ++i)
|
||||
{
|
||||
if (conne_gra[edg[i].vex1] != conne_gra[edg[i].vex2])
|
||||
{ // 如果当前边的两个顶点不在同一个连通分量中
|
||||
int tmp1 = conne_gra[edg[i].vex1], tmp2 = conne_gra[edg[i].vex2];
|
||||
for (int k = 1; k <= v; ++k)
|
||||
{ // 将所有属于tmp2的顶点合并到tmp1的连通分量中
|
||||
if (conne_gra[k] == tmp2)
|
||||
conne_gra[k] = tmp1;
|
||||
}
|
||||
ret += edg[i].val; // 将当前边的权重加到最小生成树的权重中
|
||||
}
|
||||
}
|
||||
printf("%d", ret);
|
||||
return 0;
|
||||
}
|
||||
|
||||
```
|
||||
并查集方法二
|
||||
```c
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
// 定义边结构体,包含两个顶点vex1和vex2以及它们之间的权重val (略,同上)
|
||||
// 冒泡排序函数,用于按边的权重val不减序排序边数组(略,同上)
|
||||
|
||||
// 并查集的查找操作
|
||||
int find(int m, int *father)
|
||||
{ // 如果当前节点是其自身的父节点,则直接返回该节点
|
||||
// 否则递归查找其父节点的根,并将当前节点直接连接到根节点
|
||||
return (m == father[m]) ? m : (father[m] = find(father[m], father)); // 路径压缩
|
||||
}
|
||||
|
||||
// 并查集的加入集合
|
||||
void Union(int m, int n, int *father)
|
||||
{
|
||||
int x = find(m, father);
|
||||
int y = find(n, father);
|
||||
if (x == y)
|
||||
return; // 如果发现根相同,则说明在一个集合,不用两个节点相连直接返回
|
||||
father[y] = x;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
int v, e;
|
||||
int v1, v2, val;
|
||||
int ret = 0;
|
||||
|
||||
scanf("%d%d", &v, &e);
|
||||
struct Edge *edg = (struct Edge *)malloc(sizeof(struct Edge) * e);
|
||||
int *conne_gra = (int *)malloc(sizeof(int) * (v + 1));
|
||||
|
||||
// 初始化连通图数组,每个顶点初始时只与自己相连通
|
||||
for (int i = 0; i <= v; ++i)
|
||||
{
|
||||
conne_gra[i] = i;
|
||||
}
|
||||
// 读取所有边的信息并存储到edg(存储所有边的)数组中
|
||||
for (int i = 0; i < e; ++i)
|
||||
{
|
||||
scanf("%d%d%d", &v1, &v2, &val);
|
||||
edg[i].vex1 = v1;
|
||||
edg[i].vex2 = v2;
|
||||
edg[i].val = val;
|
||||
}
|
||||
|
||||
bubblesort(edg, e); // 调用冒泡排序函数对边进行排序
|
||||
|
||||
// Kruskal算法的实现,通过边数组构建最小生成树
|
||||
int j = 0, count = 0;
|
||||
while (v > 1)
|
||||
{
|
||||
if (find(edg[j].vex1, conne_gra) != find(edg[j].vex2, conne_gra))
|
||||
{
|
||||
ret += edg[j].val; // 将当前边的权重加到最小生成树的权重中
|
||||
Union(edg[j].vex1, edg[j].vex2, conne_gra);
|
||||
v--;
|
||||
}
|
||||
j++;
|
||||
}
|
||||
printf("%d", ret);
|
||||
return 0;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
@@ -263,3 +263,97 @@ if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
```
|
||||
|
||||
|
||||
### JavaScript
|
||||
|
||||
``` JavaScript
|
||||
|
||||
function prefixSum() {
|
||||
const readline = require('readline');
|
||||
|
||||
const rl = readline.createInterface({
|
||||
input: process.stdin,
|
||||
output: process.stdout
|
||||
});
|
||||
|
||||
let inputLines = [];
|
||||
rl.on('line', (line) => {
|
||||
inputLines.push(line.trim());
|
||||
});
|
||||
|
||||
rl.on('close', () => {
|
||||
// 读取项数 n
|
||||
const n = parseInt(inputLines[0]);
|
||||
|
||||
// 使用前缀和,复杂度控制在 O(1)
|
||||
let sum = new Array(n);
|
||||
sum[0] = parseInt(inputLines[1]);
|
||||
|
||||
// 计算前缀和数组
|
||||
for (let i = 1; i < n; i++) {
|
||||
let value = parseInt(inputLines[i + 1]);
|
||||
sum[i] = sum[i - 1] + value;
|
||||
}
|
||||
|
||||
// 处理区间和查询
|
||||
for (let i = n + 1; i < inputLines.length; i++) {
|
||||
let [left, right] = inputLines[i].split(' ').map(Number);
|
||||
|
||||
if (left === 0) {
|
||||
console.log(sum[right]);
|
||||
} else {
|
||||
console.log(sum[right] - sum[left - 1]);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
||||
### C
|
||||
|
||||
```C
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int num;
|
||||
// 读取数组长度
|
||||
scanf("%d", &num);
|
||||
|
||||
// 使用动态内存分配而不是静态数组,以适应不同的输入大小
|
||||
int *a = (int *)malloc((num + 1) * sizeof(int));
|
||||
|
||||
// 初始化前缀和数组的第一个元素为0
|
||||
a[0] = 0;
|
||||
|
||||
// 读取数组元素并计算前缀和
|
||||
for (int i = 1; i <= num; i++)
|
||||
{
|
||||
int mm;
|
||||
scanf("%d", &mm);
|
||||
// 累加前缀和
|
||||
a[i] = a[i - 1] + mm;
|
||||
}
|
||||
|
||||
int m, n;
|
||||
// 循环读取区间并计算区间和,直到输入结束
|
||||
// scanf()返回成功匹配和赋值的个数,到达文件末尾则返回 EOF
|
||||
while (scanf("%d%d", &m, &n) == 2)
|
||||
{
|
||||
// 输出区间和,注意区间是左闭右开,因此a[n+1]是包含n的元素的前缀和
|
||||
printf("%d\n", a[n+1] - a[m]);
|
||||
}
|
||||
|
||||
// 释放之前分配的内存
|
||||
free(a);
|
||||
return 0;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
|
||||
@@ -425,7 +425,39 @@ public class Main {
|
||||
```
|
||||
|
||||
### Python
|
||||
```Python
|
||||
import collections
|
||||
|
||||
def main():
|
||||
n, m = map(int, input().strip().split())
|
||||
edges = [[] for _ in range(n + 1)]
|
||||
for _ in range(m):
|
||||
src, dest, weight = map(int, input().strip().split())
|
||||
edges[src].append([dest, weight])
|
||||
|
||||
minDist = [float("inf")] * (n + 1)
|
||||
minDist[1] = 0
|
||||
que = collections.deque([1])
|
||||
visited = [False] * (n + 1)
|
||||
visited[1] = True
|
||||
|
||||
while que:
|
||||
cur = que.popleft()
|
||||
visited[cur] = False
|
||||
for dest, weight in edges[cur]:
|
||||
if minDist[cur] != float("inf") and minDist[cur] + weight < minDist[dest]:
|
||||
minDist[dest] = minDist[cur] + weight
|
||||
if visited[dest] == False:
|
||||
que.append(dest)
|
||||
visited[dest] = True
|
||||
|
||||
if minDist[-1] == float("inf"):
|
||||
return "unconnected"
|
||||
return minDist[-1]
|
||||
|
||||
if __name__ == "__main__":
|
||||
print(main())
|
||||
```
|
||||
### Go
|
||||
|
||||
### Rust
|
||||
|
||||
@@ -451,6 +451,33 @@ public class Main {
|
||||
```
|
||||
|
||||
### Python
|
||||
```Python
|
||||
def main():
|
||||
n, m = map(int, input().strip().split())
|
||||
edges = []
|
||||
for _ in range(m):
|
||||
src, dest, weight = map(int, input().strip().split())
|
||||
edges.append([src, dest, weight])
|
||||
|
||||
minDist = [float("inf")] * (n + 1)
|
||||
minDist[1] = 0 # 起点处距离为0
|
||||
|
||||
for i in range(1, n):
|
||||
updated = False
|
||||
for src, dest, weight in edges:
|
||||
if minDist[src] != float("inf") and minDist[src] + weight < minDist[dest]:
|
||||
minDist[dest] = minDist[src] + weight
|
||||
updated = True
|
||||
if not updated: # 若边不再更新,即停止回圈
|
||||
break
|
||||
|
||||
if minDist[-1] == float("inf"): # 返还终点权重
|
||||
return "unconnected"
|
||||
return minDist[-1]
|
||||
|
||||
if __name__ == "__main__":
|
||||
print(main())
|
||||
```
|
||||
|
||||
### Go
|
||||
|
||||
|
||||
@@ -191,10 +191,57 @@ int main() {
|
||||
### Java
|
||||
|
||||
```java
|
||||
import java.util.*;
|
||||
|
||||
public class Main {
|
||||
public static int[][] dir = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};//下右上左逆时针遍历
|
||||
|
||||
public static void bfs(int[][] grid, boolean[][] visited, int x, int y) {
|
||||
Queue<pair> queue = new LinkedList<pair>();//定义坐标队列,没有现成的pair类,在下面自定义了
|
||||
queue.add(new pair(x, y));
|
||||
visited[x][y] = true;//遇到入队直接标记为优先,
|
||||
// 否则出队时才标记的话会导致重复访问,比如下方节点会在右下顺序的时候被第二次访问入队
|
||||
while (!queue.isEmpty()) {
|
||||
int curX = queue.peek().first;
|
||||
int curY = queue.poll().second;//当前横纵坐标
|
||||
for (int i = 0; i < 4; i++) {
|
||||
//顺时针遍历新节点next,下面记录坐标
|
||||
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 (!visited[nextX][nextY] && grid[nextX][nextY] == 1) {
|
||||
queue.add(new pair(nextX, nextY));
|
||||
visited[nextX][nextY] = true;//逻辑同上
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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];
|
||||
boolean[][] visited = new boolean[m][n];
|
||||
int ans = 0;
|
||||
for (int i = 0; i < m; i++) {
|
||||
for (int j = 0; j < n; j++) {
|
||||
grid[i][j] = sc.nextInt();
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < m; i++) {
|
||||
for (int j = 0; j < n; j++) {
|
||||
if (!visited[i][j] && grid[i][j] == 1) {
|
||||
ans++;
|
||||
bfs(grid, visited, i, j);
|
||||
}
|
||||
}
|
||||
}
|
||||
System.out.println(ans);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
@@ -182,7 +182,52 @@ int main() {
|
||||
## 其他语言版本
|
||||
|
||||
### Java
|
||||
```java
|
||||
import java.util.Scanner;
|
||||
|
||||
public class Main {
|
||||
public static int[][] dir ={{0,1},{1,0},{-1,0},{0,-1}};
|
||||
public static void dfs(boolean[][] visited,int x,int y ,int [][]grid)
|
||||
{
|
||||
for (int i = 0; i < 4; i++) {
|
||||
int nextX=x+dir[i][0];
|
||||
int nextY=y+dir[i][1];
|
||||
if(nextY<0||nextX<0||nextX>= grid.length||nextY>=grid[0].length)
|
||||
continue;
|
||||
if(!visited[nextX][nextY]&&grid[nextX][nextY]==1)
|
||||
{
|
||||
visited[nextX][nextY]=true;
|
||||
dfs(visited,nextX,nextY,grid);
|
||||
}
|
||||
}
|
||||
}
|
||||
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();
|
||||
}
|
||||
}
|
||||
boolean[][]visited =new boolean[m][n];
|
||||
int ans = 0;
|
||||
for (int i = 0; i < m; i++) {
|
||||
for (int j = 0; j < n; j++) {
|
||||
if(!visited[i][j]&&grid[i][j]==1)
|
||||
{
|
||||
ans++;
|
||||
visited[i][j]=true;
|
||||
dfs(visited,i,j,grid);
|
||||
}
|
||||
}
|
||||
}
|
||||
System.out.println(ans);
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
### Python
|
||||
|
||||
版本一
|
||||
|
||||
@@ -289,6 +289,69 @@ int main() {
|
||||
|
||||
### Java
|
||||
|
||||
```java
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class Main {
|
||||
public static List<List<Integer>> adjList = new ArrayList<>();
|
||||
|
||||
public static void dfs(boolean[] visited, int key) {
|
||||
if (visited[key]) {
|
||||
return;
|
||||
}
|
||||
visited[key] = true;
|
||||
List<Integer> nextKeys = adjList.get(key);
|
||||
for (int nextKey : nextKeys) {
|
||||
dfs(visited, nextKey);
|
||||
}
|
||||
}
|
||||
|
||||
public static void bfs(boolean[] visited, int key) {
|
||||
Queue<Integer> queue = new LinkedList<Integer>();
|
||||
queue.add(key);
|
||||
visited[key] = true;
|
||||
while (!queue.isEmpty()) {
|
||||
int curKey = queue.poll();
|
||||
List<Integer> list = adjList.get(curKey);
|
||||
for (int nextKey : list) {
|
||||
if (!visited[nextKey]) {
|
||||
queue.add(nextKey);
|
||||
visited[nextKey] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
Scanner sc = new Scanner(System.in);
|
||||
int vertices_num = sc.nextInt();
|
||||
int line_num = sc.nextInt();
|
||||
for (int i = 0; i < vertices_num; i++) {
|
||||
adjList.add(new LinkedList<>());
|
||||
}//Initialization
|
||||
for (int i = 0; i < line_num; i++) {
|
||||
int s = sc.nextInt();
|
||||
int t = sc.nextInt();
|
||||
adjList.get(s - 1).add(t - 1);
|
||||
}//构造邻接表
|
||||
boolean[] visited = new boolean[vertices_num];
|
||||
dfs(visited, 0);
|
||||
// bfs(visited, 0);
|
||||
|
||||
for (int i = 0; i < vertices_num; i++) {
|
||||
if (!visited[i]) {
|
||||
System.out.println(-1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
System.out.println(1);
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
|
||||
### Python
|
||||
BFS算法
|
||||
```Python
|
||||
@@ -327,8 +390,103 @@ if __name__ == "__main__":
|
||||
|
||||
```
|
||||
|
||||
``` python
|
||||
|
||||
def dfs(graph, key, visited):
|
||||
for neighbor in graph[key]:
|
||||
if not visited[neighbor]: # Check if the next node is not visited
|
||||
visited[neighbor] = True
|
||||
dfs(graph, neighbor, visited)
|
||||
|
||||
def main():
|
||||
import sys
|
||||
input = sys.stdin.read
|
||||
data = input().split()
|
||||
|
||||
n = int(data[0])
|
||||
m = int(data[1])
|
||||
|
||||
graph = [[] for _ in range(n + 1)]
|
||||
index = 2
|
||||
for _ in range(m):
|
||||
s = int(data[index])
|
||||
t = int(data[index + 1])
|
||||
graph[s].append(t)
|
||||
index += 2
|
||||
|
||||
visited = [False] * (n + 1)
|
||||
visited[1] = True # Process node 1 beforehand
|
||||
dfs(graph, 1, visited)
|
||||
|
||||
for i in range(1, n + 1):
|
||||
if not visited[i]:
|
||||
print(-1)
|
||||
return
|
||||
|
||||
print(1)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
|
||||
```
|
||||
|
||||
### Go
|
||||
|
||||
```go
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"os"
|
||||
)
|
||||
|
||||
func dfs(graph [][]int, key int, visited []bool) {
|
||||
visited[key] = true
|
||||
for _, neighbor := range graph[key] {
|
||||
if !visited[neighbor] {
|
||||
dfs(graph, neighbor, visited)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
scanner := bufio.NewScanner(os.Stdin)
|
||||
scanner.Scan()
|
||||
var n, m int
|
||||
fmt.Sscanf(scanner.Text(), "%d %d", &n, &m)
|
||||
|
||||
graph := make([][]int, n+1)
|
||||
for i := 0; i <= n; i++ {
|
||||
graph[i] = make([]int, 0)
|
||||
}
|
||||
|
||||
for i := 0; i < m; i++ {
|
||||
scanner.Scan()
|
||||
var s, t int
|
||||
fmt.Sscanf(scanner.Text(), "%d %d", &s, &t)
|
||||
graph[s] = append(graph[s], t)
|
||||
}
|
||||
|
||||
visited := make([]bool, n+1)
|
||||
|
||||
dfs(graph, 1, visited)
|
||||
|
||||
for i := 1; i <= n; i++ {
|
||||
if !visited[i] {
|
||||
fmt.Println(-1)
|
||||
return
|
||||
}
|
||||
}
|
||||
fmt.Println(1)
|
||||
}
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
### Rust
|
||||
|
||||
### Javascript
|
||||
|
||||
@@ -216,8 +216,131 @@ public class Main {
|
||||
|
||||
### Python
|
||||
|
||||
```python
|
||||
|
||||
def main():
|
||||
import sys
|
||||
input = sys.stdin.read
|
||||
data = input().split()
|
||||
|
||||
# 读取 n 和 m
|
||||
n = int(data[0])
|
||||
m = int(data[1])
|
||||
|
||||
# 初始化 grid
|
||||
grid = []
|
||||
index = 2
|
||||
for i in range(n):
|
||||
grid.append([int(data[index + j]) for j in range(m)])
|
||||
index += m
|
||||
|
||||
sum_land = 0 # 陆地数量
|
||||
cover = 0 # 相邻数量
|
||||
|
||||
for i in range(n):
|
||||
for j in range(m):
|
||||
if grid[i][j] == 1:
|
||||
sum_land += 1
|
||||
# 统计上边相邻陆地
|
||||
if i - 1 >= 0 and grid[i - 1][j] == 1:
|
||||
cover += 1
|
||||
# 统计左边相邻陆地
|
||||
if j - 1 >= 0 and grid[i][j - 1] == 1:
|
||||
cover += 1
|
||||
# 不统计下边和右边,避免重复计算
|
||||
|
||||
result = sum_land * 4 - cover * 2
|
||||
print(result)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
|
||||
```
|
||||
|
||||
### Go
|
||||
|
||||
```go
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func main() {
|
||||
scanner := bufio.NewScanner(os.Stdin)
|
||||
scanner.Scan()
|
||||
line := scanner.Text()
|
||||
|
||||
n, m := parseInput(line)
|
||||
|
||||
// 初始化 grid
|
||||
grid := make([][]int, n)
|
||||
for i := range grid {
|
||||
grid[i] = make([]int, m)
|
||||
}
|
||||
|
||||
// 读入 grid 数据
|
||||
for i := 0; i < n; i++ {
|
||||
scanner.Scan()
|
||||
line := scanner.Text()
|
||||
values := parseLine(line, m)
|
||||
for j := 0; j < m; j++ {
|
||||
grid[i][j] = values[j]
|
||||
}
|
||||
}
|
||||
|
||||
sum := 0 // 陆地数量
|
||||
cover := 0 // 相邻数量
|
||||
|
||||
for i := 0; i < n; i++ {
|
||||
for j := 0; j < m; j++ {
|
||||
if grid[i][j] == 1 {
|
||||
sum++ // 统计总的陆地数量
|
||||
|
||||
// 统计上边相邻陆地
|
||||
if i-1 >= 0 && grid[i-1][j] == 1 {
|
||||
cover++
|
||||
}
|
||||
// 统计左边相邻陆地
|
||||
if j-1 >= 0 && grid[i][j-1] == 1 {
|
||||
cover++
|
||||
}
|
||||
// 为什么没统计下边和右边? 因为避免重复计算
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Println(sum*4 - cover*2)
|
||||
}
|
||||
|
||||
// parseInput 解析 n 和 m
|
||||
func parseInput(line string) (int, int) {
|
||||
parts := strings.Split(line, " ")
|
||||
n, _ := strconv.Atoi(parts[0])
|
||||
m, _ := strconv.Atoi(parts[1])
|
||||
return n, m
|
||||
}
|
||||
|
||||
// parseLine 解析一行中的多个值
|
||||
func parseLine(line string, count int) []int {
|
||||
parts := strings.Split(line, " ")
|
||||
values := make([]int, count)
|
||||
for i := 0; i < count; i++ {
|
||||
values[i], _ = strconv.Atoi(parts[i])
|
||||
}
|
||||
return values
|
||||
}
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
### Rust
|
||||
|
||||
### Javascript
|
||||
|
||||
Reference in New Issue
Block a user