打卡52天------图论(应用题)

一、孤岛的总面积

基础题目 可以自己尝试做一做 。

代码随想录

复制代码
const r1 = require('readline').createInterface({ input: process.stdin });
// 创建readline接口
let iter = r1[Symbol.asyncIterator]();
// 创建异步迭代器
const readline = async () => (await iter.next()).value;

let graph // 地图
let N, M // 地图大小
let count = 0 // 孤岛的总面积
const dir = [[0, 1], [1, 0], [0, -1], [-1, 0]] //方向


// 读取输入,初始化地图
const initGraph = async () => {
  let line = await readline();
  [N, M] = line.split(' ').map(Number);
  graph = new Array(N).fill(0).map(() => new Array(M).fill(0))

  for (let i = 0; i < N; i++) {
    line = await readline()
    line = line.split(' ').map(Number)
    for (let j = 0; j < M; j++) {
      graph[i][j] = line[j]
    }
  }
}


/**
 * @description: 从(x,y)开始深度优先遍历地图
 * @param {*} graph 地图
 * @param {*} x 开始搜索节点的下标
 * @param {*} y 开始搜索节点的下标
 * @return {*}
 */
const dfs = (graph, x, y) => {
  if(graph[x][y] === 0) return
  graph[x][y] = 0 // 标记为海洋
  for (let i = 0; i < 4; i++) {
    let nextx = x + dir[i][0]
    let nexty = y + dir[i][1]
    if (nextx < 0 || nextx >= N || nexty < 0 || nexty >= M) continue
    dfs(graph, nextx, nexty)
  }
}

(async function () {

  // 读取输入,初始化地图
  await initGraph()

  // 遍历地图左右两边
  for (let i = 0; i < N; i++) {
    if (graph[i][0] === 1) dfs(graph, i, 0)
    if (graph[i][M - 1] === 1) dfs(graph, i, M - 1)
  }

  // 遍历地图上下两边
  for (let j = 0; j < M; j++) {
    if (graph[0][j] === 1) dfs(graph, 0, j)
    if (graph[N - 1][j] === 1) dfs(graph, N - 1, j)
  }

  count = 0
  // 统计孤岛的总面积
  for (let i = 0; i < N; i++) {
    for (let j = 0; j < M; j++) {
      if (graph[i][j] === 1) count++
    }
  }
  console.log(count);
})()

二、沉没孤岛

和上一题差不多,尝试自己做做

代码随想录

复制代码
const r1 = require('readline').createInterface({ input: process.stdin });
// 创建readline接口
let iter = r1[Symbol.asyncIterator]();
// 创建异步迭代器
const readline = async () => (await iter.next()).value;

let graph // 地图
let N, M // 地图大小
const dir = [[0, 1], [1, 0], [0, -1], [-1, 0]] //方向


// 读取输入,初始化地图
const initGraph = async () => {
  let line = await readline();
  [N, M] = line.split(' ').map(Number);
  graph = new Array(N).fill(0).map(() => new Array(M).fill(0))

  for (let i = 0; i < N; i++) {
    line = await readline()
    line = line.split(' ').map(Number)
    for (let j = 0; j < M; j++) {
      graph[i][j] = line[j]
    }
  }
}


/**
 * @description: 从(x,y)开始深度优先遍历地图
 * @param {*} graph 地图
 * @param {*} x 开始搜索节点的下标
 * @param {*} y 开始搜索节点的下标
 * @return {*}
 */
const dfs = (graph, x, y) => {
  if (graph[x][y] !== 1) return
  graph[x][y] = 2 // 标记为非孤岛陆地

  for (let i = 0; i < 4; i++) {
    let nextx = x + dir[i][0]
    let nexty = y + dir[i][1]
    if (nextx < 0 || nextx >= N || nexty < 0 || nexty >= M) continue
    dfs(graph, nextx, nexty)
  }
}

(async function () {

  // 读取输入,初始化地图
  await initGraph()

  // 遍历地图左右两边
  for (let i = 0; i < N; i++) {
    if (graph[i][0] === 1) dfs(graph, i, 0)
    if (graph[i][M - 1] === 1) dfs(graph, i, M - 1)
  }

  // 遍历地图上下两边
  for (let j = 0; j < M; j++) {
    if (graph[0][j] === 1) dfs(graph, 0, j)
    if (graph[N - 1][j] === 1) dfs(graph, N - 1, j)
  }


  // 遍历地图,将孤岛沉没,即将陆地1标记为0;将非孤岛陆地2标记为1
  for (let i = 0; i < N; i++) {
    for (let j = 0; j < M; j++) {
      if (graph[i][j] === 1) graph[i][j] = 0
      else if (graph[i][j] === 2) graph[i][j] = 1
    }
    console.log(graph[i].join(' '));
  }
})()

三、水流问题

需要点优化思路,建议先自己读题,相处一个解题方法,有时间就自己写代码,没时间就直接看题解,优化方式 会让你 耳目一新。

代码随想录

复制代码
const r1 = require('readline').createInterface({ input: process.stdin });
// 创建readline接口
let iter = r1[Symbol.asyncIterator]();
// 创建异步迭代器
const readline = async () => (await iter.next()).value;

let graph // 地图
let N, M // 地图大小
const dir = [[0, 1], [1, 0], [0, -1], [-1, 0]] //方向


// 读取输入,初始化地图
const initGraph = async () => {
  let line = await readline();
  [N, M] = line.split(' ').map(Number);
  graph = new Array(N).fill(0).map(() => new Array(M).fill(0))

  for (let i = 0; i < N; i++) {
    line = await readline()
    line = line.split(' ').map(Number)
    for (let j = 0; j < M; j++) {
      graph[i][j] = line[j]
    }
  }
}


/**
 * @description: 从(x,y)开始深度优先遍历地图
 * @param {*} graph 地图
 * @param {*} visited 可访问节点
 * @param {*} x 开始搜索节点的下标
 * @param {*} y 开始搜索节点的下标
 * @return {*}
 */
const dfs = (graph, visited, x, y) => {
  if (visited[x][y]) return
  visited[x][y] = true // 标记为可访问

  for (let i = 0; i < 4; i++) {
    let nextx = x + dir[i][0]
    let nexty = y + dir[i][1]
    if (nextx < 0 || nextx >= N || nexty < 0 || nexty >= M) continue //越界,跳过
    if (graph[x][y] < graph[nextx][nexty]) continue //不能流过.跳过
    dfs(graph, visited, nextx, nexty)
  }
}


/**
 * @description: 判断地图上的(x, y)是否可以到达第一组边界和第二组边界
 * @param {*} x 坐标
 * @param {*} y 坐标
 * @return {*} true可以到达,false不可以到达
 */
const isResult = (x, y) => {
  let visited = new Array(N).fill(false).map(() => new Array(M).fill(false))

  let isFirst = false //是否可到达第一边界
  let isSecond = false //是否可到达第二边界

  // 深搜,将(x, y)可到达的所有节点做标记
  dfs(graph, visited, x, y)

  // 判断能否到第一边界左边
  for (let i = 0; i < N; i++) {
    if (visited[i][0]) {
      isFirst = true
      break
    }
  }

  // 判断能否到第一边界上边
  for (let j = 0; j < M; j++) {
    if (visited[0][j]) {
      isFirst = true
      break
    }
  }

  // 判断能否到第二边界右边
  for (let i = 0; i < N; i++) {
    if (visited[i][M - 1]) {
      isSecond = true
      break
    }
  }

  // 判断能否到第二边界下边
  for (let j = 0; j < M; j++) {
    if (visited[N - 1][j]) {
      isSecond = true
      break
    }
  }

  return isFirst && isSecond
}

(async function () {

  // 读取输入,初始化地图
  await initGraph()

  // 遍历地图,判断是否能到达第一组边界和第二组边界
  for (let i = 0; i < N; i++) {
    for (let j = 0; j < M; j++) {
      if (isResult(i, j)) console.log(i + ' ' + j);
    }
  }
})()

四、建造最大岛屿

同样优化思路也会让你耳目一新,自己想比较难想出来。

代码随想录

相关推荐
SweetCode2 分钟前
裴蜀定理:整数解的奥秘
数据结构·python·线性代数·算法·机器学习
喝拿铁写前端7 分钟前
智能系统的冰山结构
前端
z_mazin12 分钟前
JavaScript逆向魔法:Chrome开发者工具探秘之旅
javascript·chrome·爬虫
ゞ 正在缓冲99%…15 分钟前
leetcode76.最小覆盖子串
java·算法·leetcode·字符串·双指针·滑动窗口
绿草在线15 分钟前
Mock.js虚拟接口
开发语言·javascript·ecmascript
xuanjiong16 分钟前
纯个人整理,蓝桥杯使用的算法模板day2(0-1背包问题),手打个人理解注释,超全面,且均已验证成功(附带详细手写“模拟流程图”,全网首个
算法·蓝桥杯·动态规划
惊鸿.Jh35 分钟前
【滑动窗口】3254. 长度为 K 的子数组的能量值 I
数据结构·算法·leetcode
明灯L35 分钟前
《函数基础与内存机制深度剖析:从 return 语句到各类经典编程题详解》
经验分享·python·算法·链表·经典例题
碳基学AI41 分钟前
哈尔滨工业大学DeepSeek公开课:探索大模型原理、技术与应用从GPT到DeepSeek|附视频与讲义免费下载方法
大数据·人工智能·python·gpt·算法·语言模型·集成学习
补三补四1 小时前
机器学习-聚类分析算法
人工智能·深度学习·算法·机器学习