首页 > 其他分享 >【代码随想录——图论——小岛问题】

【代码随想录——图论——小岛问题】

时间:2024-07-15 10:57:13浏览次数:13  
标签:图论 int make 随想录 ++ newX 小岛 sea visited

1.水流问题

在这里插入图片描述
使用两个visited数组即可。

1.1 DFS版

package main

import "fmt"

var direction = [][]int{{0, 1}, {0, -1}, {1, 0}, {-1, 0}}

func main() {
	var M, N int
	fmt.Scanln(&N, &M)
	sea := make([][]int, N)
	one_visited := make([][]bool, N)
	two_visited := make([][]bool, N)
	for i := 0; i < N; i++ {
		sea[i] = make([]int, M)
		one_visited[i] = make([]bool, M)
		two_visited[i] = make([]bool, M)
	}

	for i := 0; i < N; i++ {
		for j := 0; j < M; j++ {
			fmt.Scan(&sea[i][j])
		}
	}

	for i := 0; i < N; i++ {
		dfs(i, 0, N, M, &sea, &one_visited)
		dfs(i, M-1, N, M, &sea, &two_visited)
	}

	for j := 0; j < M; j++ {
		dfs(0, j, N, M, &sea, &one_visited)
		dfs(N-1, j, N, M, &sea, &two_visited)
	}

	for i := 0; i < N; i++ {
		for j := 0; j < M; j++ {
			if one_visited[i][j] && two_visited[i][j] {
				fmt.Printf("%d %d\n", i, j)
			}
		}
	}

}

func dfs(x, y, N, M int, sea *[][]int, visited *[][]bool) {
	if (*visited)[x][y] {
		return
	}
	(*visited)[x][y] = true

	for i := 0; i < 4; i++ {
		newX := x + direction[i][0]
		newY := y + direction[i][1]
		if newX < 0 || newX >= N || newY < 0 || newY >= M {
			continue
		}
		if (*sea)[newX][newY] > (*sea)[x][y] && !(*visited)[newX][newY] {
			dfs(newX, newY, N, M, sea, visited)
		}
	}
}

1.2 BFS版

package main

import "fmt"

var direction = [][]int{{0, 1}, {0, -1}, {1, 0}, {-1, 0}}

func main() {
	var M, N int
	fmt.Scanln(&N, &M)
	sea := make([][]int, N)
	one_visited := make([][]bool, N)
	two_visited := make([][]bool, N)
	for i := 0; i < N; i++ {
		sea[i] = make([]int, M)
		one_visited[i] = make([]bool, M)
		two_visited[i] = make([]bool, M)
	}

	for i := 0; i < N; i++ {
		for j := 0; j < M; j++ {
			fmt.Scan(&sea[i][j])
		}
	}

	for i := 0; i < N; i++ {
		bfs(i, 0, N, M, &sea, &one_visited)
		bfs(i, M-1, N, M, &sea, &two_visited)
	}

	for j := 0; j < M; j++ {
		bfs(0, j, N, M, &sea, &one_visited)
		bfs(N-1, j, N, M, &sea, &two_visited)
	}

	for i := 0; i < N; i++ {
		for j := 0; j < M; j++ {
			if one_visited[i][j] && two_visited[i][j] {
				fmt.Printf("%d %d\n", i, j)
			}
		}
	}

}
func bfs(x, y, N, M int, sea *[][]int, visited *[][]bool) int {
	if (*visited)[x][y] {
		return 0
	}
	queue := make([][2]int, 0)
	queue = append(queue, [2]int{x, y})
	(*visited)[x][y] = true
	area := 0
	for len(queue) != 0 {
		pos := queue[0]
		queue = queue[1:]
		area += 1
		for i := 0; i < 4; i++ {
			newX := pos[0] + direction[i][0]
			newY := pos[1] + direction[i][1]
			if newX < 0 || newX >= N || newY < 0 || newY >= M {
				continue
			}
			if (*sea)[newX][newY] > (*sea)[pos[0]][pos[1]] && !(*visited)[newX][newY] {
				queue = append(queue, [2]int{newX, newY})
				(*visited)[newX][newY] = true
			}
		}
	}
	return area
}

2.建造最大岛屿

在这里插入图片描述

package main

import "fmt"

var direction = [][]int{{0, 1}, {0, -1}, {1, 0}, {-1, 0}}
var M, N int

func main() {

	fmt.Scanln(&N, &M)
	sea := make([][]int, N)
	visited := make([][]bool, N)
	island := make(map[int]int, 0)
	for i := 0; i < N; i++ {
		sea[i] = make([]int, M)
		visited[i] = make([]bool, M)
	}

	for i := 0; i < N; i++ {
		for j := 0; j < M; j++ {
			fmt.Scan(&sea[i][j])
		}
	}

	isLandIndex := 1
	for i := 0; i < N; i++ {
		for j := 0; j < M; j++ {
			if sea[i][j] == 1 && !visited[i][j] {
				area := 0
				dfs(i, j, isLandIndex, &sea, &visited, &area)
				island[isLandIndex] = area
				isLandIndex += 1
			}
		}
	}
	maxArea := 1
	for _, area := range island {
		if area > maxArea {
			maxArea = area
		}
	}
	for i := 0; i < N; i++ {
		for j := 0; j < M; j++ {
			if sea[i][j] == 0 {
				//尝试在这里建造小岛
				area := 1
				connIsland := make([]int, 0)
				for k := 0; k < 4; k++ {
					newX := i + direction[k][0]
					newY := j + direction[k][1]
					if newX < 0 || newX >= N || newY < 0 || newY >= M {
						continue
					}
					if sea[newX][newY] != 0 && !isInList(sea[newX][newY], connIsland) {
						area += island[sea[newX][newY]]
						connIsland = append(connIsland, sea[newX][newY])
					}
				}
				if area > maxArea {
					maxArea = area
				}
			}
		}
	}
	//for key, value := range island {
	//	fmt.Printf("小岛编号:%d,小岛面积:%d \n", key, value)
	//}
	fmt.Println(maxArea)
}

func isInList(isLandIndex int, isLands []int) bool {
	for i := 0; i < len(isLands); i++ {
		if isLandIndex == isLands[i] {
			return true
		}
	}
	return false
}

func dfs(x, y, seaIndex int, sea *[][]int, visited *[][]bool, area *int) {
	(*visited)[x][y] = true
	(*sea)[x][y] = seaIndex
	*area = (*area) + 1
	for i := 0; i < 4; i++ {
		newX := x + direction[i][0]
		newY := y + direction[i][1]
		if newX < 0 || newX >= N || newY < 0 || newY >= M {
			continue
		}
		if (*sea)[newX][newY] == 1 && !(*visited)[newX][newY] {
			dfs(newX, newY, seaIndex, sea, visited, area)
		}
	}
}

3.字符串接龙

在这里插入图片描述

package main

import "fmt"

var N int
var beginStr, endStr string

func main() {
	fmt.Scanln(&N)
	fmt.Scanf("%s %s", &beginStr, &endStr)
	strList := make([]string, 0)
	strMap := make(map[string]int)
	strMap[beginStr] = 0
	strMap[endStr] = 1
	strList = append(strList, beginStr)
	strList = append(strList, endStr)
	strIndex := 2
	for i := 0; i < N; i++ {
		var tempStr string
		fmt.Scanln(&tempStr)
		strMap[tempStr] = strIndex
		strList = append(strList, tempStr)
		strIndex++
	}
	if beginStr == endStr {
		fmt.Println(0)
		return
	}
	m := make([][]int, N+2)
	for i := 0; i < N+2; i++ {
		m[i] = make([]int, N+2)
	}
	for i := 0; i < N+2; i++ {
		for j := i; j < N+2; j++ {
			if canTransfer(strList[i], strList[j]) {
				m[i][j] = 1
				m[j][i] = 1
			}
		}
	}

	//printMatrix(m)
	// 开启bfs
	step := bfs(0, 1, &m)
	fmt.Println(step)
}

func canTransfer(str1, str2 string) bool {
	diff := 0
	for i := 0; i < len(str1); i++ {
		if str1[i] != str2[i] {
			diff++
		}
	}
	return diff == 1
}

func bfs(beginIndex, endIndex int, m *[][]int) int {
	queue := make([]int, 0)
	tempQueue := make([]int, 0)
	queue = append(queue, beginIndex)
	strSet := make(map[int]struct{})
	strSet[beginIndex] = struct{}{}
	step := 1
	for len(queue) != 0 {
		nowIndex := queue[0]
		if nowIndex == endIndex {
			return step
		}
		queue = queue[1:]
		for i := 0; i < N+2; i++ {
			_, ok := strSet[i]
			if ok {
				continue
			}
			if (*m)[nowIndex][i] == 1 {
				tempQueue = append(tempQueue, i)
				//表示已经在队列中
				strSet[i] = struct{}{}
			}
		}
		if len(queue) == 0 {
			for i := 0; i < len(tempQueue); i++ {
				queue = append(queue, tempQueue[i])
			}
			tempQueue = make([]int, 0)
			step++
		}
	}
	return 0
}

4.有向图的完全可达性

在这里插入图片描述

package main

import "fmt"

var directions = [4][2]int{
	{0, 1},
	{0, -1},
	{1, 0},
	{-1, 0},
}
var N, M int

func main() {
	fmt.Scanln(&N, &M)
	m := make([][]int, N+1)
	visited := make([]bool, N+1)
	for i := 0; i < N+1; i++ {
		m[i] = make([]int, N+1)
	}
	for i := 0; i < M; i++ {
		var start, end int
		fmt.Scanln(&start, &end)
		m[start][end] = 1
	}
	//bfs
	reachCount := bfs(1, &visited, &m)
	if reachCount == N {
		fmt.Println(1)
	} else {
		fmt.Println(-1)
	}
}

func bfs(start int, visited *[]bool, m *[][]int) int {
	queue := make([]int, 0)
	queue = append(queue, start)
	(*visited)[start] = true
	reachCount := 1
	for len(queue) != 0 {
		now := queue[0]
		queue = queue[1:]
		for i := 1; i < N+1; i++ {
			if !(*visited)[i] && (*m)[now][i] == 1 {
				queue = append(queue, i)
				(*visited)[i] = true
				reachCount++
			}
		}
	}
	return reachCount
}

5.岛屿的周长

在这里插入图片描述

package main

import "fmt"

var directions = [4][2]int{
	{0, 1},
	{0, -1},
	{1, 0},
	{-1, 0},
}
var N, M int

func main() {
	fmt.Scanln(&N, &M)
	m := make([][]int, N)
	for i := 0; i < N; i++ {
		m[i] = make([]int, M)
	}
	for i := 0; i < N; i++ {
		for j := 0; j < M; j++ {
			fmt.Scan(&m[i][j])
		}
	}
	//遍历map并向四方探索
	result := 0
	for i := 0; i < N; i++ {
		for j := 0; j < M; j++ {
			if m[i][j] == 1 {
				result += getEdgeNum(i, j, &m)
			}
		}
	}
	fmt.Println(result)
}

func getEdgeNum(x, y int, m *[][]int) int {
	edge := 4
	for i := 0; i < 4; i++ {
		newX := x + directions[i][0]
		newY := y + directions[i][1]
		if newX < 0 || newX >= N || newY < 0 || newY >= M{
			continue
		}
		if (*m)[newX][newY] == 1{
			edge--
		}
	}
	return edge
}

标签:图论,int,make,随想录,++,newX,小岛,sea,visited
From: https://blog.csdn.net/qq_45467608/article/details/140271880

相关文章

  • Day68 代码随想录打卡|回溯算法篇---子集
    题目(leecodeT78):给你一个整数数组 nums ,数组中的元素 互不相同 。返回该数组所有可能的子集(幂集)。解集 不能 包含重复的子集。你可以按 任意顺序 返回解集。方法:本题为求子集问题,采用回溯算法解决,与之前的组合与分割问题我们最后收集的是树上的叶子节点不同。子集......
  • 【代码随想录|第十一章 图论part01 | 797.所有可能的路径 】
    代码随想录|第十一章图论part01|图论理论基础,797.所有可能的路径,广搜理论基础一、图论理论基础1.图的基本概念2.图的构造1)邻接矩阵2)邻接表3.图的遍历方式4.深度优先搜索理论基础二、797.所有可能的路径1.核心代码2.问题三、广搜理论基础总结python一、图论理......
  • 代码随想录算法训练营第10天|232. 用栈实现队列,225. 用队列实现栈,20. 有效的括号,1047.
    学习任务:Leetcode232.用栈实现队列Leetcode225.用队列实现栈Leetcode20.有效的括号Leetcode1047.删除字符串中的所有相邻重复项Leetcode232.用栈实现队列难度:简单|相关标签:栈、设计、队列题目:请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支......
  • 二十个基于 Python 的 NetworkX 图论算法库入门应用实例
    前言大家好,最近我在美丽的重庆度过了一段美好的学习时光。重庆以其独特的山城地貌和美食闻名,而在火锅和享受美食之余,这里的项目学习激发了我对图论的兴趣。图论是一门既古老又新兴的学科,它在计算机科学、网络分析、社会网络、物流优化等领域有着广泛的应用。而Python的......
  • Day66 代码随想录打卡|回溯算法篇---分割回文串
    题目(leecodeT131):给你一个字符串 s,请你将 s 分割成一些子串,使每个子串都是 回文串。返回 s 所有可能的分割方案。方法:本题是一个分割回文串的问题,是回溯算法的另一类问题。针对一个字符串,我们要对其进行分割,并且确保分割后生成的子串也必须全都是回文串。分析回溯三......
  • 代码随想录day 23 组合总和 | 组合总和II | 分割回文串
    组合总和组合总和解题思路利用回溯算法进行遍历,由于数组内的数字可以重复调用,因此在套用模板进行遍历时,下一次递归的startIndex是当前遍历的下标。剪枝操作则是通过比较和是否大于目标值,如果大于则不进行下一次的递归,以此来减少循环遍历的次数,这个条件需要加到for循环中。知......
  • 【代码随想录|回溯算法 77. 组合】
    代码随想录|回溯算法77.组合,216.组合总和III,17.电话号码的字母组合一、77.组合1.核心代码2.输入输出3.问题总结python一、77.组合内容77.组合1.核心代码代码如下(示例):classSolution:defcombine(self,n:int,k:int)->List[List[int]]:......
  • 「代码随想录算法训练营」第十天 | 栈与队列 part2
    150.逆波兰表达式求值题目链接:https://leetcode.cn/problems/evaluate-reverse-polish-notation/题目难度:中等文章讲解:https://programmercarl.com/0150.逆波兰表达式求值.html视频讲解:https://www.bilibili.com/video/BV1kd4y1o7on题目状态:多次修改bug后通过个人思路:......
  • 代码随想录——不同路径(Leetcode LCR98)
    题目链接动态规划classSolution{publicintuniquePaths(intm,intn){int[][]dp=newint[m][n];//从(0,0)到(i,0)路径只有一条for(inti=0;i<m;i++){dp[i][0]=1;}//从(0,0)到(0,j)路......
  • 代码随想录——不同路径Ⅱ(Leetcode 63)
    题目链接动态规划classSolution{publicintuniquePathsWithObstacles(int[][]obstacleGrid){intm=obstacleGrid.length;intn=obstacleGrid[0].length;int[][]dp=newint[m][n];//遇到障碍则从(0,0)到达......