当前位置: 首页 > news >正文

牛客周赛Round 99(Go语言)

A题 (A.go)

思路总结: 这道题要求判断一个整数中是否包含连续的两个'9'。

核心思路是将输入的整数转换为字符串,然后遍历这个字符串,检查是否存在相邻的两个字符都是'9'。如果找到了,就立即停止遍历并输出"YES";如果遍历完整个字符串都没有找到,则输出"NO"。

// ==========================================================
//                    POWERED BY GMJ
//                   2025-07-06 18:26
// ==========================================================
// Github:     https://github.com/Joker-0111-G
// CSDN:       https://blog.csdn.net/dl999666?type=blog
// Gmail:      joker0111gmj@gmail.com
// Author:     USER <joker0111gmj@gmail.com>
// FilePath:   ~/homegmj/GoCode/NK/20250706\A.go
// License:    MIT
// Copyright:  (c) 2025 JOKER. All rights reserved.
// ==========================================================
//    __  __    _  _____ _   _  ____ __  __     _
//    \ \/ /   / \|_   _| | | |/ ___|  \/  |   | |
//     \  /   / _ \ | | | | | | |  _| |\/| |_  | |
//     /  \  / ___ \| | | |_| | |_| | |  | | |_| |
//    /_/\_\/_/   \_\_|  \___/ \____|_|  |_|\___/
// ==========================================================
// Project Description (use | for new lines)package mainimport ("fmt""strconv"
)func mainA() {var n intfmt.Scan(&n) s := strconv.Itoa(n)found99 := false for i := 0; i < len(s)-1; i++ {if s[i] == '9' && s[i+1] == '9' {found99 = true break       }}if found99 {fmt.Println("YES") } else {fmt.Println("NO")  }
}
B题 (B.go)

思路总结: 题目要求找到输入字符串中ASCII码最大的字符,并输出其ASCII码值。

解法非常直接:初始化一个变量ma为0,用来记录当前遇到的最大ASCII码。然后遍历输入字符串中的每一个字符,将其转换为对应的ASCII整数值。在遍历过程中,如果当前字符的ASCII值大于ma,就更新ma。遍历结束后,ma中存储的就是整个字符串中最大的ASCII码值,直接输出即可。

// ==========================================================
//                    POWERED BY GMJ                         
//                   2025-07-06 19:02
// ==========================================================
// Github:     https://github.com/Joker-0111-G
// CSDN:       https://blog.csdn.net/dl999666?type=blog
// Gmail:      joker0111gmj@gmail.com
// Author:     USER <joker0111gmj@gmail.com>
// FilePath:   ~/homegmj/GoCode/NK/20250706\B.go
// License:    MIT
// Copyright:  (c) 2025 JOKER. All rights reserved.
// ==========================================================
//    __  __    _  _____ _   _  ____ __  __     _
//    \ \/ /   / \|_   _| | | |/ ___|  \/  |   | |
//     \  /   / _ \ | | | | | | |  _| |\/| |_  | |
//     /  \  / ___ \| | | |_| | |_| | |  | | |_| |
//    /_/\_\/_/   \_\_|  \___/ \____|_|  |_|\___/
// ==========================================================
// Project Description (use | for new lines)package mainimport ("bufio""fmt""os"
)func mainB() {reader := bufio.NewReader(os.Stdin)var T intfmt.Fscan(reader, &T) for t := 0; t < T; t++ {var n intfmt.Fscan(reader, &n) var s stringfmt.Fscan(reader, &s)ma := 0 for _, char := range s {as := int(char)if as > ma {ma = as}}fmt.Println(ma) }
}
C题 (C.go)

思路总结: 这道题的目标是构造一个由'4'和'8'组成的、总价值为k的最小数字。"4"的价值是1,"8"的价值是2。

为了让构造出的数字最小,位数应该尽可能少。因为'8'的价值(2)是'4'的价值(1)的两倍,所以应该优先使用'8'来减少位数。

具体策略是:

  1. k对2进行整除,商a表示需要多少个'8'。

  2. k对2取模,如果余数为1 (b=true),说明还需要一个价值为1的'4'。

  3. 为了使数字最小,较小的数字'4'应该放在较高的位(即最前面)。所以,如果需要'4',就先在结果中添加一个'4'。

  4. 然后,在后面追加a个'8'。

  5. 特殊情况:如果k=0,价值为0,无法用'4'或'8'表示,但题目可能要求输出一个有效数字,根据代码逻辑,此时输出'1'(可能是题目特定要求或默认值)。

// ==========================================================
//                    POWERED BY GMJ                         
//                   2025-07-06 19:04
// ==========================================================
// Github:     https://github.com/Joker-0111-G
// CSDN:       https://blog.csdn.net/dl999666?type=blog
// Gmail:      joker0111gmj@gmail.com
// Author:     USER <joker0111gmj@gmail.com>
// FilePath:   ~/homegmj/GoCode/NK/20250706\C.go
// License:    MIT
// Copyright:  (c) 2025 JOKER. All rights reserved.
// ==========================================================
//    __  __    _  _____ _   _  ____ __  __     _
//    \ \/ /   / \|_   _| | | |/ ___|  \/  |   | |
//     \  /   / _ \ | | | | | | |  _| |\/| |_  | |
//     /  \  / ___ \| | | |_| | |_| | |  | | |_| |
//    /_/\_\/_/   \_\_|  \___/ \____|_|  |_|\___/
// ==========================================================
// Project Description (use | for new lines)package mainimport ("bufio""fmt""os""strings"
)func mainC() {reader := bufio.NewReader(os.Stdin)writer := bufio.NewWriter(os.Stdout)defer writer.Flush() var T intfmt.Fscan(reader, &T) for i := 0; i < T; i++ {var k intfmt.Fscan(reader, &k) if k == 0 {fmt.Fprintln(writer, 1) continue}a := k / 2b := (k % 2 == 1)var res strings.Builder if b {res.WriteByte('4') }for j := 0; j < a; j++ {res.WriteByte('8')}fmt.Fprintln(writer, res.String()) }
}
D题 (D.go)

思路总结: 这是一道数学或逻辑推导题。给定xp,需要计算一个结果。

通过分析代码逻辑 a := p / xb := p - a,我们可以推断这可能与某种分配或分组有关。 核心判断在于 p % x == 0

  • 如果 p 能被 x 整除,结果是 2*a - 1。这里的 a 就是 p/x

  • 如果 p 不能被 x 整除,结果是 2 * b。这里的 bp - p/x

这暗示了两种不同的计算场景。在能整除的情况下,可能存在某种合并或特殊状态,导致结果减1。在不能整除的情况下,则是基于p和商a的差值进行计算。解题的关键是理解这两种情况对应的具体数学模型。

// ==========================================================
//                    POWERED BY GMJ                         
//                   2025-07-06 19:10
// ==========================================================
// Github:     https://github.com/Joker-0111-G
// CSDN:       https://blog.csdn.net/dl999666?type=blog
// Gmail:      joker0111gmj@gmail.com
// Author:     USER <joker0111gmj@gmail.com>
// FilePath:   ~/homegmj/GoCode/NK/20250706\D.go
// License:    MIT
// Copyright:  (c) 2025 JOKER. All rights reserved.
// ==========================================================
//    __  __    _  _____ _   _  ____ __  __     _
//    \ \/ /   / \|_   _| | | |/ ___|  \/  |   | |
//     \  /   / _ \ | | | | | | |  _| |\/| |_  | |
//     /  \  / ___ \| | | |_| | |_| | |  | | |_| |
//    /_/\_\/_/   \_\_|  \___/ \____|_|  |_|\___/
// ==========================================================
// Project Description (use | for new lines)package mainimport ("bufio""fmt""os"
)func mainD() {reader := bufio.NewReader(os.Stdin)writer := bufio.NewWriter(os.Stdout)defer writer.Flush() var T intfmt.Fscan(reader, &T) for i := 0; i < T; i++ {var x, p intfmt.Fscan(reader, &x, &p) a := p / x b := p - avar res intif p%x == 0 {res = 2*a - 1}else{res = 2 * b}fmt.Fprintln(writer, res) }
}
E题 (E.go)

思路总结: 这道题是一道动态规划(DP)问题。目标是求解对一个数组进行操作后,需要移除多少个只出现一次的元素。

问题可以转化为:最多能保留多少个只出现一次的元素。

我们定义DP状态:

  • dp0: 表示处理到第 i 个元素时,不选择第 i 个元素能保留的最多独特元素数量。

  • dp1: 表示处理到第 i 个元素时,选择第 i 个元素(前提是a[i]是独特元素且满足某种条件)能保留的最多独特元素数量。

状态转移方程: 遍历数组 a1n

  1. 计算 next_dp0 (不选当前元素 a[i-1]):

    • 可以从 dp0 (前一个也不选) 转移而来。

    • 也可以从 dp1 (前一个选了) 转移而来,只要满足不冲突的条件 (如 a[i-2] < i)。

    • next_dp0 = max(dp0, dp1_if_valid)

  2. 计算 next_dp1 (选择当前元素 a[i-1]):

    • 首先,a[i-1] 必须是只出现一次的元素。

    • 可以从 dp0 转移:dp0 + 1,需满足条件 (如 i-1 < a[i-1])。

    • 可以从 dp1 转移:dp1 + 1,需满足条件 (如 a[i-2] < a[i-1])。

    • next_dp1 = max(dp0_to_dp1, dp1_to_dp1)

遍历结束后,max(dp0, dp1) 就是最多能保留的独特元素数量 maxLen

最终答案是 总的独特元素数量 - maxLen

// ==========================================================
//
//	POWERED BY GMJ
//	2025-07-06 19:18
//
// ==========================================================
// Github:      https://github.com/Joker-0111-G
// CSDN:        https://blog.csdn.net/dl999666?type=blog
// Gmail:       joker0111gmj@gmail.com
// Author:      USER <joker0111gmj@gmail.com>
// FilePath:    ~/homegmj/GoCode/NK/20250706/E_fixed.go
// License:     MIT
// Copyright:   (c) 2025 JOKER. All rights reserved.
// ==========================================================
//
//	__  __    _  _____ _  _  ____ __  __     _
//	\ \/ /   / \|_   _| | | |/ ___|  \/  |   | |
//	 \  /   / _ \ | | | | | | |  _| |\/| |_  | |
//	 /  \  / ___ \| | | |_| | |_| | |  | | |_| |
//	/_/\_\/_/   \_\_|  \___/ \____|_|  |_|\___/
//
// ==========================================================
package mainimport ("bufio""fmt""os""strconv"
)var (in     = bufio.NewScanner(os.Stdin)out    = bufio.NewWriter(os.Stdout)negInf = -1 << 30
)func init() {in.Split(bufio.ScanWords)
}func readInt() int {in.Scan()n, _ := strconv.Atoi(in.Text())return n
}func max(a, b int) int {if a > b {return a}return b
}func solve() {n := readInt()a := make([]int, n)freq := make(map[int]int)for i := 0; i < n; i++ {val := readInt()a[i] = valfreq[val]++}numTotalUnique := len(freq)isUnique := make(map[int]bool)for val, count := range freq {if count == 1 {isUnique[val] = true}}dp0 := 0dp1 := negInffor i := 1; i <= n; i++ {a_i := a[i-1]ndp0_from_dp0 := dp0ndp0_from_dp1 := negInfif i > 1 {if a[i-2] < i {ndp0_from_dp1 = dp1}}next_dp0 := max(ndp0_from_dp0, ndp0_from_dp1)next_dp1 := negInfif isUnique[a_i] {ndp1_from_dp0 := negInfif i-1 < a_i {ndp1_from_dp0 = dp0 + 1}ndp1_from_dp1 := negInfif i > 1 {if a[i-2] < a_i {ndp1_from_dp1 = dp1 + 1}}next_dp1 = max(ndp1_from_dp0, ndp1_from_dp1)}dp0 = next_dp0dp1 = next_dp1}maxLen := max(dp0, dp1)fmt.Fprintln(out, numTotalUnique-maxLen)
}func mainE() {defer out.Flush()t := readInt()for t > 0 {solve()t--}
}
F题 (F.go)

思路总结: 这道题要求在满足特定条件下找到一个最大的整数 h。条件是:n 可以表示为 m 个数 x_i 的和(n = x_1 + ... + x_m),其中每个 x_i 都大于等于 h,并且 x_ih 的按位与(bitwise AND)都为0。

核心思路是贪心 + 位运算检验

  1. 贪心策略: 从高位到低位(例如从第30位开始)尝试构建 h。我们希望 h 尽可能大,所以优先尝试将高位置为1。

  2. 构建过程:

    • 初始化答案 ans = 0

    • b = 300 循环。

    • 在每一位 b,我们尝试将 ans 的第 b 位置为1,形成一个临时的 h,即 h = ans | (1 << b)

  3. 检验可行性:

    • 将每个 x_i 分解为 h + y_i。因为 x_i & h == 0,所以 x_i >= h 等价于 y_i >= 0y_i & h == 0

    • 原方程 n = sum(x_i) 变为 n = sum(h + y_i) = m*h + sum(y_i)

    • 我们需要检验 rem = n - m*h (剩余部分) 是否能被分配到 my_i 中,同时满足 y_i >= 0y_i & h == 0

    • 这个检验过程由 check(rem, m, h) 函数完成。

  4. check函数逻辑:

    • 该函数通过从高位到低位逐位处理 rem 来判断分配是否可能。

    • 它维护一个 debt(债务)变量。对于 rem 的每一位,如果 h 的对应位是1,那么 y_i 的这一位必须是0,所以 rem 在这一位的1不能被分配,会累积成“债务”传递给更低的位。

    • 如果 h 的对应位是0,那么 y_i 的这一位可以是1,我们可以用这m个数来“偿还”债务。最多可以偿还 m

    • 如果在任何时候债务过大(溢出风险),或者到最后债务没有清零,则说明分配失败。

  5. 更新答案:

    • 如果 check 函数返回 true,说明将第 b 位置为1是可行的,我们更新 ans = h

    • 否则,保持 ans 不变,继续尝试下一位。

最终得到的 ans 就是满足条件的最大 h

// ==========================================================
//                    POWERED BY GMJ
//                   2025-07-06 19:25
// ==========================================================
// Github:     https://github.com/Joker-0111-G
// CSDN:       https://blog.csdn.net/dl999666?type=blog
// Gmail:      joker0111gmj@gmail.com
// Author:     USER <joker0111gmj@gmail.com>
// FilePath:   ~/homegmj/GoCode/NK/20250706\F.go
// License:    MIT
// Copyright:  (c) 2025 JOKER. All rights reserved.
// ==========================================================
//    __  __    _  _____ _   _  ____ __  __     _
//    \ \/ /   / \|_   _| | | |/ ___|  \/  |   | |
//     \  /   / _ \ | | | | | | |  _| |\/| |_  | |
//     /  \  / ___ \| | | |_| | |_| | |  | | |_| |
//    /_/\_\/_/   \_\_|  \___/ \____|_|  |_|\___/
// ==========================================================
// Project Description (use | for new lines)package mainimport ("bufio""fmt""os"
)// max devuelve el mayor de dos enteros int64.
func max(a, b int64) int64 {if a > b {return a}return b
}// check determina si 'rem' (el resto) se puede escribir como la suma
// de 'm' enteros no negativos, donde cada uno es bitwise ortogonal a 'h'.
func check(rem int64, m int64, h int64) bool {var debt int64 = 0 // 'debt' acumula la deuda desde los bits más significativos.// Iteramos desde un bit alto para manejar cualquier acarreo de forma segura.for j := 62; j >= 0; j-- {// Si ya no quedan bits en 'rem' y la deuda es cero, podemos parar.if debt == 0 && (rem>>j) == 0 {continue}// Si la deuda es demasiado grande, es imposible que se pague.// Esto previene el desbordamiento (overflow) de 'debt'.// 1<<62 es una cota segura que está por debajo del límite de int64.if debt >= (1 << 62) {return false}// Acumulamos la deuda, desplazándola e incluyendo el bit actual de 'rem'.debt = debt*2 + (rem>>j)&1// Si el bit j está "permitido" (h_j == 0), podemos usar nuestros 'm'// créditos para pagar la deuda.if (h>>j)&1 == 0 {debt = max(0, debt-m)}}// Si al final del proceso la deuda es cero, la distribución es posible.return debt == 0
}func mainF() {in := bufio.NewReader(os.Stdin)out := bufio.NewWriter(os.Stdout)defer out.Flush()var T intfmt.Fscan(in, &T)for t := 0; t < T; t++ {var n, m int64fmt.Fscan(in, &n, &m)var ans int64 = 0// Estrategia greedy: construir la respuesta desde el bit más significativo (30).for b := 30; b >= 0; b-- {h := ans | (1 << b)// Si m*h > n, es imposible. Usamos n/m para evitar desbordamientos.if h > n/m {continue}rem := n - m*h// Verificamos si este resto se puede distribuir correctamente.if check(rem, m, h) {// Si es posible, aceptamos este bit.ans = h}}fmt.Fprintln(out, ans)}
}

http://www.lryc.cn/news/581619.html

相关文章:

  • 【前端工程化】前端工作中的业务规范有哪些
  • 4.2 如何训练⼀个 LLM
  • Redis主从切换踩坑记:当Redisson遇上分布式锁的“死亡连接“
  • 鼓式制动器的设计+(说明书和CAD【6张】 - 副本➕降重
  • ClickHouse 全生命周期性能优化
  • Linux内核(一)
  • 【unity小技巧】在 Unity 中将 2D 精灵添加到 3D 游戏中,并实现阴影投射效果,实现类《八分旅人》《饥荒》等等的2.5D游戏效果
  • [leetcode] C++ 并查集模板
  • SQL 一键转 GORM 模型,支持字段注释、类型映射、tag 自定义!
  • D435i + ROS2
  • Kali制作Linux木马
  • C++ i386/AMD64平台汇编指令对齐长度获取实现
  • 基于ARM+FPGA的光栅尺精密位移加速度测试解决方案
  • React 英语单词消消乐一款专为英语学习设计的互动式记忆游戏
  • 第一次ctf比赛的赛后复现记录
  • 中国首家“小柯剧场音乐剧学院”正式成立
  • JavaScript 中导入模块时,确实不需要显式地写 node_modules 路径。
  • obs开发调研
  • 基于springboot的社区生鲜团购系统
  • # IS-IS 协议 | LSP 传输与链路状态数据库同步机制
  • 【黑马点评】(二)缓存
  • 模块化汽车基础设施的正面交锋---区域架构与域架构
  • QT 菜单栏设计使用方法
  • brpc怎么解决C++静态初始化顺序难题的?
  • golang 协程 如何中断和恢复
  • React 各颜色转换方法、颜色值换算工具HEX、RGB/RGBA、HSL/HSLA、HSV、CMYK
  • 存储延时数据,帮你选数据库和缓存架构
  • 微前端架构在嵌入式BI中的集成实践与性能优化
  • 20250706-4-Docker 快速入门(上)-常用容器管理命令_笔记
  • Windows 11 Enterprise LTSC 转 IoT