2021-07-17:一个不含有负数的数组可以代表一圈环形山,每个位置的值代表山的高度。比如, {3,1,2,4,5}、{4,5,3,1,2}或{1,2,4,5,3}都代表同样结构的环形山。山峰A和山
2021-07-17:一个不含有负数的数组可以代表一圈环形山,每个位置的值代表山的高度。比如, {3,1,2,4,5}、{4,5,3,1,2}或{1,2,4,5,3}都代表同样结构的环形山。山峰A和山峰B能够相互看见的条件为: 1.如果A和B是同一座山,认为不能相互看见,2.如果A和B是不同的山,并且在环中相邻,认为可以相互看见,3.如果A和B是不同的山,并且在环中不相邻,假设两座山高度的最小值为min,1)如果A通过顺时针方向到B的途中没有高度比min大的山峰,认为A和B可以相互看见,2)如果A通过逆时针方向到B的途中没有高度比min大的山峰,认为A和B可以相互看见。两个方向只要有一个能看见,就算A和B可以相互看见。给定一个不含有负数且没有重复值的数组 arr,请返回有多少对山峰能够相互看见。进阶问题:给定一个不含有负数但可能含有重复值的数组arr,返回有多少对山峰能够相互看见。
福大大 答案2021-07-17:
时间紧,见代码。
代码用golang编写。代码如下:
package main
import (
"container/list"
"fmt"
)
func main() {
arr := []int{3, 1, 2, 4, 5, 3, 1, 2, 4, 5}
ret := getVisibleNum(arr)
fmt.Println(ret)
}
// 栈中放的记录,
// value就是指,times是收集的个数
type Record struct {
value int
times int
}
func NewRecord(value int) *Record {
ret := &Record{}
ret.value = value
ret.times = 1
return ret
}
func twoSelectOne(c bool, a int, b int) int {
if c {
return a
} else {
return b
}
}
func getVisibleNum(arr []int) int {
if len(arr) < 2 {
return 0
}
N := len(arr)
maxIndex := 0
// 先在环中找到其中一个最大值的位置,哪一个都行
for i := 0; i < N; i++ {
maxIndex = twoSelectOne(arr[maxIndex] < arr[i], i, maxIndex)
}
stack := list.New().Init()
// 先把(最大值,1)这个记录放入stack中
stack.PushBack(NewRecord(arr[maxIndex]))
// 从最大值位置的下一个位置开始沿next方向遍历
index := nextIndex(maxIndex, N)
// 用“小找大”的方式统计所有可见山峰对
res := 0
// 遍历阶段开始,当index再次回到maxIndex的时候,说明转了一圈,遍历阶段就结束
for index != maxIndex {
// 当前数要进入栈,判断会不会破坏第一维的数字从顶到底依次变大
// 如果破坏了,就依次弹出栈顶记录,并计算山峰对数量
for stack.Back().Value.(*Record).value < arr[index] {
k := stack.Back().Value.(*Record).times
stack.Remove(stack.Back())
// 弹出记录为(X,K),如果K==1,产生2对; 如果K>1,产生2*K + C(2,K)对。
res += getInternalSum(k) + 2*k
}
// 当前数字arr[index]要进入栈了,如果和当前栈顶数字一样就合并
// 不一样就把记录(arr[index],1)放入栈中
if stack.Back().Value.(*Record).value == arr[index] {
stack.Back().Value.(*Record).times++
} else { // >
stack.PushBack(NewRecord(arr[index]))
}
index = nextIndex(index, N)
}
// 清算阶段开始了
// 清算阶段的第1小阶段
for stack.Len() > 2 {
times := stack.Back().Value.(*Record).times
stack.Remove(stack.Back())
res += getInternalSum(times) + 2*times
}
// 清算阶段的第2小阶段
if stack.Len() == 2 {
times := stack.Back().Value.(*Record).times
stack.Remove(stack.Back())
res += getInternalSum(times) + twoSelectOne(stack.Back().Value.(*Record).times == 1, times, 2*times)
}
// 清算阶段的第3小阶段
res += getInternalSum(stack.Back().Value.(*Record).times)
stack.Remove(stack.Back())
return res
}
// 如果k==1返回0,如果k>1返回C(2,k)
func getInternalSum(k int) int {
return twoSelectOne(k == 1, 0, k*(k-1)/2)
}
// 环形数组中当前位置为i,数组长度为size,返回i的下一个位置
func nextIndex(i int, size int) int {
return twoSelectOne(i < (size-1), i+1, 0)
}
执行结果如下:

2021-07-17:一个不含有负数的数组可以代表一圈环形山,每个位置的值代表山的高度。比如, {3,1,2,4,5}、{4,5,3,1,2}或{1,2,4,5,3}都代表同样结构的环形山。山峰A和山的更多相关文章
- 2021.07.17 题解 CF1385E Directing Edges(拓扑排序)
2021.07.17 题解 CF1385E Directing Edges(拓扑排序) CF1385E Directing Edges - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) ...
- 2021.07.17 P4170 染色(区间DP)
2021.07.17 P4170 染色(区间DP) [P4170 CQOI2007]涂色 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 重点: 1.目标状态可以由哪些状态转移过来. ...
- 2021.07.17 P3177 树上染色(树形DP)
2021.07.17 P3177 树上染色(树形DP) [P3177 HAOI2015]树上染色 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 重点: 1.dp思想是需要什么,维护 ...
- 2021.07.09 K-D树
2021.07.09 K-D树 前置知识 1.二叉搜索树 2.总是很长的替罪羊树 K-D树 建树 K-D树具有二叉搜索树的形态,对于每一个分类标准,小于标准的节点在父节点左边,大于标准的节点在父节点右 ...
- 2021.07.23 P2474 天平(差分约束)
2021.07.23 P2474 天平(差分约束) [P2474 SCOI2008]天平 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 题意: 已知A,B和每两个点点权,求点权i, ...
- 2021.07.19 P2294 狡猾的商人(差分约束)
2021.07.19 P2294 狡猾的商人(差分约束) [P2294 HNOI2005]狡猾的商人 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 重点: 1.差分约束最长路与最短 ...
- 2021.07.26 P1022 计算器的改良(字符串)
2021.07.26 P1022 计算器的改良(字符串) 改进: 如果是我出题,我一定把未知数设为ab.buh.bluesky之类的长度不只是1的字符串! 题意: 一个一元一次方程,求解. 分析: 1 ...
- 2021.07.23 P3275 糖果(差分约束)
2021.07.23 P3275 糖果(差分约束) [P3275 SCOI2011]糖果 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 重点: 1.为了满足更多更多约束条件,合适地 ...
- 2021.07.19 BZOJ2654 tree(生成树)
2021.07.19 BZOJ2654 tree(生成树) tree - 黑暗爆炸 2654 - Virtual Judge (vjudge.net) 重点: 1.生成树的本质 2.二分 题意: 有一 ...
- 面试题:给定一个长度为N的数组,其中每个元素的取值范围都是1到N。判断数组中是否有重复的数字
题目:给定一个长度为N的数组,其中每个元素的取值范围都是1到N.判断数组中是否有重复的数字.(原数组不必保留) 方法1.对数组进行排序(快速,堆),然后比较相邻的元素是否相同.时间复杂度为O(nlog ...
随机推荐
- 自己动手从零写桌面操作系统GrapeOS系列教程——12.QEMU+GDB调试
学习操作系统原理最好的方法是自己写一个简单的操作系统. 写程序不免需要调试,写不同的程序调试方式也不同.如果做应用软件开发,相应的程序调试方式是建立在有操作系统支持的基础上的.而我们现在是要开发操作系 ...
- 自己动手从零写桌面操作系统GrapeOS系列教程——16.封装打印字符串函数
学习操作系统原理最好的方法是自己写一个简单的操作系统. 在上一讲中我们向屏幕打印字符串"GrapeOS"用了十几行汇编代码,如果要输出的字符比较多,这种方法太繁琐了.本讲我们将打印 ...
- 声网Agora Lipsync 技术揭秘:通过实时语音驱动人像模拟真人说话
元宇宙的火热让人们对未来虚拟世界的形态充满了幻想,此前我们为大家揭秘了声网自研的 3D 空间音频技术如何在虚拟世界中完美模拟现实听觉体验,增加玩家沉浸感.今天我们暂时离开元宇宙,回到现实世界,来聊聊声 ...
- GUI编程--3 Swing
GUI编程-3 Swing 3.1 JFrame 窗口 窗口: package com.ssl.lesson04; import javax.swing.*; import java.awt.*; p ...
- MyBatisPlus 整合 SpringBoot 遇见的问题(一)
[异常]:UnsatisfiedDependencyException: Error creating bean with name 'xxx[类]': Unsatisfied dependency ...
- Django笔记十之values_list指定字段取值及distinct去重处理
这篇笔记将介绍 reverse.distinct.values 和 values_list 的用法. 本篇笔记目录如下: reverse() values() values_list() distin ...
- 企业信息化-3.6 IT资源管理2-系统及应用
笔者从业的主要是App Dev&Ops,对操作系统有些了解,对应用软件了解的更多.以下是总结了以前跟Host&Server Service.Cloud Service.IT Solut ...
- 快速使用ChatGpt Web Server
快速使用ChatGpt Web Server ChatGpt Web Server是使用Blazor Server模式部署的一个服务,所有的逻辑和代码执行都会在服务器执行,然后通过SignalR传输到 ...
- Kubernetes(k8s)实现IPv4/IPv6网络双栈
背景 如今IPv4IP地址已经使用完毕,未来全球会以IPv6地址为中心,会大力发展IPv6网络环境,由于IPv6可以实现给任何一个设备分配到公网IP,所以资源是非常丰富的. 配置hosts [root ...
- 关于 IDP 的五大认知误解
内部开发者平台(IDP)是近年来在希望加快软件交付和改善开发者体验的企业中得到普及的一个概念.然而,大众对于什么是 IDP 以及它能为开发者和企业带来什么也有很多困惑和误解.在这篇文章中,我们将尝试解 ...