csp信奥赛C++高频考点专项训练之前缀和&差分 --【一维前缀和】:宝石串

csp信奥赛C++高频考点专项训练之前缀和&差分 --【一维前缀和】:宝石串

题目描述

有一种宝石串,由绿宝石和红宝石串成,仅当绿宝石和红宝石数目相同的时候,宝石串才最为稳定,不易断裂。安安想知道从给定的宝石串中,可以截取一段最长的稳定的宝石串,有多少颗宝石组成。请你帮助他。

绿宝石用 G \texttt G G 表示,红宝石用 R \texttt R R 表示。

输入格式

一行,一个由 G \texttt G G 和 R \texttt R R 组成的字符串。

输出格式

一行一个整数,表示最长的稳定的宝石串有多少颗宝石组成。

输入输出样例 1
输入 1
复制代码
GRGGRG
输出 1
复制代码
4
说明/提示

RGGR \texttt {RGGR} RGGR 为答案。

宝石数小于等于 10 6 10^6 106。

思路分析

将绿宝石 G 视为数值 +1,红宝石 R 视为数值 -1。问题转化为:在给定整数序列(由 +1-1 组成)中,寻找最长的连续子段,其和为 0

经典解法:计算前缀和 pre[i](表示前 i 个字符的数值和),那么子段 [l+1, r] 的和为 pre[r] - pre[l]。要使和为 0,需要 pre[r] == pre[l]。因此,对于每个位置 i,记录前缀和 cur 第一次出现的位置 first[cur],当再次遇到相同前缀和时,从第一次出现的位置 +1 到当前位置的子段和即为 0,长度为 i - first[cur]。遍历所有位置,更新最大长度即可。

前缀和的范围为 [-n, n]n 为字符串长度),可以通过加偏移量 n 映射到非负下标,用数组快速访问。初始时,前缀和为 0 对应的位置为 -1(表示空串),便于计算从开头开始的合法子串。

时间复杂度 O(n),空间复杂度 O(n)

代码实现

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;

int main(){
    string s;cin>>s;//输入字符串
    int n=s.size();//长度
    int d=n;//偏移量,使下标非负
    vector<int> f(2*n+5,-2);//记录每个前缀和首次出现的位置,-2表示未出现
    f[d]=-1;//前缀和0的位置设为-1
    int cur=0,maxl=0;//当前前缀和,最大长度
    for(int i=0;i<n;i++){//遍历每个字符
        cur+=(s[i]=='G'?1:-1);//更新前缀和,G为+1,R为-1
        int idx=cur+d;//映射后的下标
        if(f[idx]==-2) f[idx]=i;//首次出现则记录位置
        else maxl=max(maxl,i-f[idx]);//否则计算长度并更新答案
    }
    cout<<maxl<<'\n';//输出结果
    return 0;
}

功能分析

  • 输入处理 :读取一行仅含 GR 的字符串。
  • 前缀和转换 :将 G 视为 +1R 视为 -1,实时计算前缀和。
  • 哈希数组 :利用偏移量将前缀和映射到数组下标,记录每个前缀和首次出现的位置,初始时将前缀和 0 映射到位置 -1
  • 最长子段查找:遍历每个字符,如果当前前缀和之前出现过,则计算子段长度并更新最大值;否则记录当前位置。
  • 输出结果 :输出最长稳定宝石串的长度(即 GR 数量相等的最长连续子串长度)。

【完整系列请查看专栏】:
信奥赛C++普及组CSP-J一等奖通关刷题题单及题解:
https://blog.csdn.net/weixin_66461496/category_12673810.html 点击跳转


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

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
int main(){
	cout<<"##########  一站式掌握信奥赛知识!  ##########";
	cout<<"#############  冲刺信奥赛拿奖!  #############";
	cout<<"######  课程购买后永久学习,不受限制!   ######";
	return 0;
}

【秘籍汇总】(完整csp信奥赛C++学习资料):

1、csp/信奥赛C++,完整信奥赛系列课程(永久学习):

https://edu.csdn.net/lecturer/7901 点击跳转

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

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

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

3、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 点击跳转

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

信奥赛C++普及组CSP-J一等奖通关刷题题单及题解:
https://blog.csdn.net/weixin_66461496/category_12673810.html 点击跳转

信奥赛C++提高组csp-j初赛&复赛真题题解(持续更新): https://blog.csdn.net/weixin_66461496/category_12808781.html 点击跳转

信奥赛C++提高组csp-s初赛&复赛真题题解(持续更新):
https://blog.csdn.net/weixin_66461496/category_13125089.html 点击跳转

5、GESP C++考级真题题解:

GESP(C++ 一级+二级+三级)真题题解(持续更新):https://blog.csdn.net/weixin_66461496/category_12858102.html 点击跳转

GESP(C++ 四级+五级+六级)真题题解(持续更新):https://blog.csdn.net/weixin_66461496/category_12869848.html 点击跳转

GESP(C++ 七级+八级)真题题解(持续更新):
https://blog.csdn.net/weixin_66461496/category_13117178.html 点击跳转

· 文末祝福 ·

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
int main(){
	cout<<"跟着王老师一起学习信奥赛C++";
	cout<<"    成就更好的自己!       ";
	cout<<"  csp信奥赛一等奖属于你!   ";
	return 0;
}
相关推荐
fqbqrr21 小时前
2606C++,C++构的多态
开发语言·c++
小欣加油21 小时前
leetcode56 合并区间
c++·算法·leetcode·职场和发展
Yolo_TvT1 天前
C++:析构函数
c++
Hello:CodeWorld1 天前
C 风格变参 vs C++ 变参模板:核心区别与选型指南
c语言·c++·算法
搬砖魁首1 天前
基础能力系列 - 多线程2 - 条件变量
c++·rust·条件变量·原子类型·线程同步互斥
chase_my_dream1 天前
C++ + SLAM 高频面试问题整理
开发语言·c++·面试
牛油果子哥q1 天前
【C++ STL string 】C++ STL string 终极精讲:底层原理、内存机制、全套API、深浅拷贝、易错坑点与工程实战规范
数据库·c++
凡人叶枫1 天前
Effective C++ 条款04:确定对象被使用前已先被初始化
java·linux·开发语言·c++·嵌入式开发
不想写代码的星星1 天前
std::move 根本不移动,就像老婆饼里没有老婆
c++
redaijufeng1 天前
C++雾中风景7:闭包
c++·算法·风景