牛客春招刷题训练营-2025.4.9题解
活动地址: 牛客春招刷题训练营 - 编程打卡活动
简单题 求最大连续bit数
- 输入一个整数 
n - 通过位运算遍历这个整数的每一位(从低位到高位,总共64位):
- 使用 
n>>i将数字右移 i 位 - 使用 
&1判断最低位是否为1 
 - 使用 
 - 使用两个变量:
l:记录当前连续1的长度ans:记录最大连续1的长度
 - 遍历过程中:
- 如果当前位是1,则 
l加1 - 如果当前位是0,则比较 
l和ans,更新ans,并将l重置为0 
 - 如果当前位是1,则 
 - 最后还需要再检查一次 
l和ans(处理最后一段连续1的情况) - 输出 
ans即为结果 
package main
import "fmt"
func main() {
	var n int
	fmt.Scan(&n)
	ans, l := 0, 0
	for i := 0; i < 64; i++ {
		if n>>i&1 == 1 {
			l++
		} else {
			if l > ans {
				ans = l
			}
			l = 0
		}
	}
	if l > ans {
		ans = l
	}
	fmt.Println(ans)
}
中等题 小红的排列构造
因为题意可知构造出的数组一定是个排列,所以 01 串中最后一位一定是 1,不是 1 的一定无解。
然后遍历 01 串每次遇到1时就对前面的数组位置进行一个填充,一个简单的思路就是末项为当前没有填充的数组最小,其余位置依次递增(即 2,3,4,5 的排列变为 3,4,5,2),这样一定保证前面位置不能构成排列,只有最后一项能够成为排列。
package main
import "fmt"
func main() {
	var (
		n int
		s string
	)
	fmt.Scan(&n, &s)
	s = " " + s
	if s[n] == '0' {
		fmt.Println(-1)
		return
	}
	a := make([]int, n+1)
	l := 1
	for i := 1; i <= n; i++ {
		if s[i] == '1' {
			for j := l; j < i; j++ {
				a[j] = l + j - l + 1
			}
			a[i] = l
			l = i + 1
		}
	}
	for i := 1; i <= n; i++ {
		fmt.Printf("%d ", a[i])
	}
}
困难题 [NOIP2001]装箱问题
这道题是一个经典的0-1 背包问题,目标是将物品放入容量为 V 的背包中,使得背包中物品的总重量尽可能接近 V,但不超过 V。最后输出背包剩余的空间。
- 
定义状态:
- 使用 
dp[j]表示容量为j的背包所能容纳的最大重量。 
 - 使用 
 - 
状态转移方程:
- 
对于每个物品重量
x,从背包容量V开始向下遍历:dp[j] = max(dp[j], dp[j-x] + x)这里的含义是:当前容量
j的最大重量,要么不放入当前物品(保持dp[j]不变),要么放入当前物品(更新为dp[j-x] + x)。 
 - 
 - 
初始化:
dp[0] = 0,表示容量为 0 的背包最大重量为 0。- 其他 
dp[j]初始为 0,因为还没有放入任何物品。 
 - 
遍历顺序:
- 外层循环遍历所有物品。
 - 内层循环从背包容量 
V向下遍历,确保每个物品只能被使用一次(0-1 背包的特性)。 
 - 
输出结果:
- 最后,
dp[V]表示容量为V的背包所能容纳的最大重量。 - 剩余空间为 
V - dp[V]。 
 - 最后,
 
package main
import "fmt"
func main() {
	var V, n int
	fmt.Scan(&V, &n)
	dp := make([]int, V+1)
	for i := 0; i < n; i++ {
		var x int
		fmt.Scan(&x)
		for j := V; j >= x; j-- {
			if dp[j-x]+x > dp[j] {
				dp[j] = dp[j-x] + x
			}
		}
	}
	fmt.Println(V - dp[V])
}
#牛客春招刷题训练营#牛客春招刷题训练营 文章被收录于专栏
 爱丽姐真是太好了

查看14道真题和解析
