牛客春招刷题训练营-2025.3.27题解
活动地址: 牛客春招刷题训练营 - 编程打卡活动
简单题 杨辉三角的变形
- 前两行因为元素个数太少,不存在偶数
- 因为每行第二个位置是 n-1,所以奇数行第一个偶数出现的位置为 2
- 多推几项可以发现第一个偶数出现的位置循环节为 2324
package main
import (
"fmt"
)
func main() {
var n int
fmt.Scan(&n)
if n <= 2 {
fmt.Println(-1)
} else if n%2 == 1 {
fmt.Println(2)
} else if n%4 == 0 {
fmt.Println(3)
} else {
fmt.Println(4)
}
}
中等题 计算日期到天数转换
- 程序接收输入的年、月、日(y, m, d)
- 判断是否为闰年:
- 如果年份能被4整除但不能被100整除,或者能被400整除,则为闰年
- 闰年2月有29天,平年2月有28天
- 计算当前日期是一年中的第几天:
- 将该月份之前所有月份的天数累加
- 再加上当月的天数
package main
import "fmt"
var days = []int{0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30}
func isLeapYear(year int) bool {
if year%4 == 0 && year%100 != 0 || year%400 == 0 {
return true
}
return false
}
func main() {
var y, m, d int
fmt.Scan(&y, &m, &d)
if isLeapYear(y) {
days[2] = 29
}
s := 0
for i := 1; i < m; i++ {
s += days[i]
}
s += d
fmt.Println(s)
}
困难题 而后单调
要想让操作后是严格递增或严格递减数组,所以挑选出的长度为 m 的连续子数组一定要是原数组排序后元素之间是相邻且有序的。
所以问题转换成了判断一个数组中是否存在长度为m
的连续子数组,该子数组中的元素在排序后是连续递增或连续递减的。
-
解题步骤:
- 首先读入数组长度
n
和目标长度m
,以及数组a
- 使用
map
检查数组中是否有重复元素,如果有重复则直接输出"NO" - 创建数组
b
作为a
的副本并排序,用于取每个元素的排序后位置 - 使用
map
记录每个元素在排序后数组中的位置索引
- 首先读入数组长度
-
动态规划部分:
- 创建两个dp数组:
dp1[]
:记录以当前位置结尾的连续递增子序列长度dp2[]
:记录以当前位置结尾的连续递减子序列长度
- 创建两个dp数组:
-
状态转移:
- 对于每个位置
i
:- 如果当前元素在排序后位置比前一个元素大1,则
dp1[i] = dp1[i-1] + 1
- 如果当前元素在排序后位置比前一个元素小1,则
dp2[i] = dp2[i-1] + 1
- 否则重置为1
- 如果当前元素在排序后位置比前一个元素大1,则
- 对于每个位置
-
最后判断:
- 遍历所有位置,如果存在任意位置的
dp1[i]
或dp2[i]
等于m
,则输出"YES" - 否则输出"NO"
- 遍历所有位置,如果存在任意位置的
时间复杂度:,主要来自排序
空间复杂度:,用于存储dp数组和map
package main
import (
"fmt"
"sort"
)
func solve() {
var n, m int
fmt.Scan(&n, &m)
a := make([]int, n)
b := make([]int, n)
mp := make(map[int]int)
for i := 0; i < n; i++ {
fmt.Scan(&a[i])
b[i] = a[i]
mp[a[i]] = -1
}
if len(mp) != n {
fmt.Println("NO")
return
}
sort.Ints(b)
for i := 0; i < n; i++ {
mp[b[i]] = i
}
dp1, dp2 := make([]int, n), make([]int, n)
dp1[0], dp2[0] = 1, 1
for i := 1; i < n; i++ {
if mp[a[i]]-mp[a[i-1]] == 1 {
dp1[i] = dp1[i-1] + 1
} else {
dp1[i] = 1
}
if mp[a[i]]-mp[a[i-1]] == -1 {
dp2[i] = dp2[i-1] + 1
} else {
dp2[i] = 1
}
}
for i := 0; i < n; i++ {
if dp1[i] == m || dp2[i] == m {
fmt.Println("YES")
return
}
}
fmt.Println("NO")
}
func main() {
var t int
fmt.Scan(&t)
for i := 0; i < t; i++ {
solve()
}
}
#牛客春招刷题训练营#牛客春招刷题训练营 文章被收录于专栏
爱丽姐真是太好了