news 2026/6/19 23:47:54

2025年12月GESP真题及题解(C++八级): 宝石项链

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
2025年12月GESP真题及题解(C++八级): 宝石项链

2025年12月GESP真题及题解(C++八级): 宝石项链

题目描述

小 A 有一串包含n nn枚宝石的宝石项链,这些宝石按照在项链中的顺序依次以1 , 2 , … , n 1,2,\ldots,n1,2,,n编号,第n nn枚宝石与第1 11枚宝石相邻。项链由m mm种宝石组成,其中第i ii枚宝石种类为t i t_iti

小 A 想将宝石项链分给他的好朋友们。具体而言,小 A 会将项链划分为若干连续段,并且需要保证每段都包含全部m mm种宝石。请帮小 A 计算在满足条件的前提下,宝石项链最多可以划分为多少段。

输入格式

第一行,两个正整数n , m n,mn,m,分别表示宝石项链中的宝石的数量与种类数。

第二行,n nn个正整数t 1 , t 2 , … , t n t_1,t_2,\ldots,t_nt1,t2,,tn,表示每枚宝石的种类。

输出格式

输出一行,一个整数,表示宝石项链最多可以划分的段数。

输入输出样例 1
输入 1
6 2 1 2 1 2 1 2
输出 1
3
输入输出样例 2
输入 2
7 3 3 1 3 1 2 1 2
输出 2
2
说明/提示

对于40 % 40\%40%的测试点,保证2 ≤ n ≤ 1000 2\le n\le 10002n1000

对于所有测试点,保证2 ≤ n ≤ 10 5 2\le n\le 10^52n1052 ≤ m ≤ n 2\le m\le n2mn1 ≤ t i ≤ m 1\le t_i\le m1tim,保证1 , 2 , … , m 1,2,\ldots,m1,2,,m均在t 1 , t 2 , … , t n t_1,t_2,\ldots,t_nt1,t2,,tn中出现。

思路分析

这是一个环形数组划分问题。我们需要将一个环形宝石项链(第n个宝石与第1个宝石相邻)划分为若干连续段,每段必须包含全部m种宝石,求最多能划分多少段。

核心难点
  1. 环形结构:数组是环形的,需要考虑循环的情况
  2. 最短包含所有宝石的段:要划分尽可能多的段,每段应该是包含所有m种宝石的最短连续段
  3. 贪心策略:每次找到最短的合法段,然后从下一位置继续寻找
算法思路
  1. 环形处理:将原数组复制一份接在后面,形成2n长度的数组,这样环形问题转化为线性问题
  2. 滑动窗口:使用双指针维护一个包含所有m种宝石的最短窗口
  3. 贪心划分
    • 从起点开始,找到最短的包含所有宝石的段
    • 记录这个段的结束位置,然后从下一个位置继续寻找
    • 重复直到覆盖整个环形数组
  4. 最大化段数:由于是环形,不同起点可能导致不同结果,需要尝试所有起点
时间复杂度优化
  • 朴素方法:对于每个起点O(n)寻找,总O(n²),会超时
  • 优化方法:使用**倍增法(Binary Lifting)**预处理每个位置开始跳转的信息
    • 预处理:对于每个位置i,计算从i开始取一段后下一个起点的位置
    • 倍增表:f[i][k]表示从i开始取2^k段后到达的位置
    • 查询:对于每个起点,用倍增快速计算最多能取多少段
具体步骤
  1. 数据准备:复制数组为2n长度
  2. 滑动窗口预处理
    • 对于每个位置i,找到以i为起点的最短合法段的结束位置
    • 记录next[i] = 结束位置 + 1(下一段的起点)
  3. 构建倍增表
    • f[i][0] = next[i](跳1段)
    • f[i][k] = f[f[i][k-1]][k-1](跳2^k段)
  4. 枚举起点计算
    • 对每个起点i,用倍增法计算最多能跳多少段
    • 保持结束位置不超过i+n(环形限制)
  5. 取最大值:所有起点结果的最大值

代码实现

#include<bits/stdc++.h>usingnamespacestd;constintMAXN=2e5+5;// 2倍长度constintLOG=20;// 2^20 > 1e6intn,m;intt[MAXN];// 宝石数组(已复制为2倍长度)intcnt[MAXN];// 计数数组,记录当前窗口每种宝石数量intnxt[MAXN];// nxt[i]: 从i开始取一段后下一个起点位置intf[MAXN][LOG];// 倍增表:f[i][k]表示从i开始取2^k段后到达的位置intmain(){// 读入数据cin>>n>>m;for(inti=0;i<n;i++){cin>>t[i];t[i+n]=t[i];// 复制一份,处理环形}// 滑动窗口预处理每个位置的下一个起点inttypes=0;// 当前窗口内宝石种类数intr=0;// 右指针// 初始化计数数组for(inti=1;i<=m;i++)cnt[i]=0;// 遍历每个位置作为左端点for(intl=0;l<2*n;l++){// 扩展右指针,直到窗口包含所有m种宝石while(r<2*n&&types<m){cnt[t[r]]++;if(cnt[t[r]]==1)types++;r++;}// 如果找到了包含所有宝石的窗口,记录下一个起点if(types==m){nxt[l]=r;// 结束位置+1就是下一段起点}else{nxt[l]=2*n;// 标记为无效位置}// 移动左指针前,减少计数cnt[t[l]]--;if(cnt[t[l]]==0)types--;}// 构建倍增表// 初始化:跳2^0=1段for(inti=0;i<2*n;i++){f[i][0]=nxt[i];}// 计算2^k段for(intk=1;k<LOG;k++){for(inti=0;i<2*n;i++){if(f[i][k-1]<2*n){f[i][k]=f[f[i][k-1]][k-1];}else{f[i][k]=2*n;// 超出范围}}}// 枚举每个起点,计算最多段数intans=0;for(intstart=0;start<n;start++){intpos=start;// 当前位置intseg=0;// 段数// 从大到小尝试跳转for(intk=LOG-1;k>=0;k--){if(f[pos][k]<=start+n){// 跳2^k段后不超过环形范围seg+=(1<<k);// 增加段数pos=f[pos][k];// 更新位置}}ans=max(ans,seg);}cout<<ans<<endl;return0;}

功能分析

1. 数据预处理部分
// 复制数组处理环形for(inti=0;i<n;i++){t[i+n]=t[i];}
  • 目的:将环形问题转化为线性问题
  • 原理:在长度为2n的数组上,任何长度为n的窗口都对应原环形数组的一个起始位置
2. 滑动窗口预处理
while(r<2*n&&types<m){cnt[t[r]]++;if(cnt[t[r]]==1)types++;r++;}
  • 功能:对于每个左端点l,找到最短的包含所有m种宝石的右端点
  • 变量说明
    • types:当前窗口内不同宝石的种类数
    • cnt[]:记录每种宝石的出现次数
    • nxt[l]:从l开始取一段后,下一段的起始位置
3. 倍增表构建
for(intk=1;k<LOG;k++){for(inti=0;i<2*n;i++){if(f[i][k-1]<2*n){f[i][k]=f[f[i][k-1]][k-1];}}}
  • 原理f[i][k] = f[f[i][k-1]][k-1]表示从i跳2k段等价于先跳2(k-1)段,再跳2^(k-1)段
  • LOG选择:2^20 ≈ 1e6 > 2×1e5,足够覆盖所有可能跳转
4. 枚举起点计算
for(intk=LOG-1;k>=0;k--){if(f[pos][k]<=start+n){seg+=(1<<k);pos=f[pos][k];}}
  • 贪心策略:从高位向低位尝试跳转
  • 约束条件f[pos][k] <= start + n确保跳转后不超过环形范围
  • 时间复杂度:每个起点O(log n),总O(n log n)
5. 算法复杂度
  • 时间复杂度:O(n log n)
    • 滑动窗口预处理:O(n)(每个元素进出各一次)
    • 倍增表构建:O(n log n)
    • 枚举起点计算:O(n log n)
  • 空间复杂度:O(n log n)(主要存储倍增表)
6. 关键点总结
  1. 环形处理技巧:数组复制是处理环形问题的常用方法
  2. 滑动窗口优化:双指针法在线性时间内找到所有最短合法段
  3. 倍增法应用:将多次跳转压缩为对数级别查询
  4. 贪心正确性:每次取最短段能最大化段数,这是本题的关键性质
7. 示例解析

以样例1为例:

n=6, m=2 宝石序列: 1 2 1 2 1 2
  • 最短合法段长度均为2(包含1和2)
  • 可以划分为3段:[1,2]、[1,2]、[1,2]
  • 代码会找到所有起点中的最优解

各种学习资料,助力大家一站式学习和提升!!!

#include<bits/stdc++.h>usingnamespacestd;intmain(){cout<<"########## 一站式掌握信奥赛知识! ##########";cout<<"############# 冲刺信奥赛拿奖! #############";cout<<"###### 课程购买后永久学习,不受限制! ######";return0;}

1、csp信奥赛高频考点知识详解及案例实践:

CSP信奥赛C++动态规划:
https://blog.csdn.net/weixin_66461496/category_13096895.html点击跳转

CSP信奥赛C++标准模板库STL:
https://blog.csdn.net/weixin_66461496/category_13108077.html 点击跳转

信奥赛C++提高组csp-s知识详解及案例实践:
https://blog.csdn.net/weixin_66461496/category_13113932.html

2、csp信奥赛冲刺一等奖有效刷题题解:

CSP信奥赛C++初赛及复赛高频考点真题解析(持续更新):https://blog.csdn.net/weixin_66461496/category_12808781.html 点击跳转

CSP信奥赛C++一等奖通关刷题题单及题解(持续更新):https://blog.csdn.net/weixin_66461496/category_12673810.html 点击跳转

3、CSP信奥赛C++竞赛拿奖视频课:

https://edu.csdn.net/course/detail/40437 点击跳转

· 文末祝福 ·

#include<bits/stdc++.h>usingnamespacestd;intmain(){cout<<"跟着王老师一起学习信奥赛C++";cout<<" 成就更好的自己! ";cout<<" csp信奥赛一等奖属于你! ";return0;}
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/18 23:23:02

Misra C++与CI/CD流水线集成:自动化检测方案设计

将 Misra C 静态分析深度融入 CI/CD&#xff1a;打造高可靠代码的自动化防线在汽车电子、工业控制和医疗设备等安全关键领域&#xff0c;一个指针越界、一次资源泄漏&#xff0c;都可能引发灾难性后果。面对日益复杂的C代码库&#xff0c;如何系统性地规避语言陷阱&#xff1f;…

作者头像 李华
网站建设 2026/6/15 18:41:53

手把手教你用Qwen2.5-0.5B-Instruct搭建智能编程助手

手把手教你用Qwen2.5-0.5B-Instruct搭建智能编程助手 在当前AI驱动的开发浪潮中&#xff0c;大语言模型&#xff08;LLM&#xff09;正逐步成为程序员的“第二大脑”。阿里云推出的 Qwen2.5-0.5B-Instruct 是一款轻量级但功能强大的指令调优语言模型&#xff0c;特别适合部署为…

作者头像 李华
网站建设 2026/6/15 1:16:57

智能打码系统参数调优:AI人脸隐私卫士高级技巧

智能打码系统参数调优&#xff1a;AI人脸隐私卫士高级技巧 1. 背景与挑战&#xff1a;为何需要智能打码系统&#xff1f; 在社交媒体、新闻报道和公共监控等场景中&#xff0c;图像和视频的广泛传播带来了巨大的隐私泄露风险。尤其是人脸信息&#xff0c;作为不可更改的生物特…

作者头像 李华
网站建设 2026/6/13 16:16:02

AI手势识别与追踪车载系统:驾驶中免触控操作实现

AI手势识别与追踪车载系统&#xff1a;驾驶中免触控操作实现 在智能汽车快速发展的今天&#xff0c;人机交互方式正经历深刻变革。传统的物理按键和触摸屏操作虽然直观&#xff0c;但在驾驶过程中容易分散驾驶员注意力&#xff0c;带来安全隐患。为解决这一痛点&#xff0c;AI…

作者头像 李华
网站建设 2026/6/15 22:17:59

App自动化测试入门:APP测试的定义及环境搭建处理

随着移动应用的快速发展&#xff0c;App测试变得越来越重要。而自动化测试成为了提高测试效率和质量的关键手段之一。本文将从零开始&#xff0c;详细介绍App自动化测试的定义&#xff0c;并指导你如何搭建测试环境。 一、App测试的定义 App测试是指通过模拟用户操作和行为&a…

作者头像 李华
网站建设 2026/6/17 9:06:34

DDU清理NVIDIA驱动:系统级深度剖析教程

DDU 清理 NVIDIA 驱动&#xff1a;一次彻底的系统级“大扫除” 你有没有遇到过这样的情况&#xff1f;明明刚重装了最新版 NVIDIA 显卡驱动&#xff0c;结果一进游戏就闪退&#xff1b;或者开机后屏幕一片漆黑&#xff0c;主机风扇呼呼转着&#xff0c;就是没信号。更离谱的是…

作者头像 李华