题目详情
链接:https://www.nowcoder.com/questionTerminal/e10ed38e315442fc9772004c58582c8f
来源:牛客网
游游拿到了一个长度为n的字符串,她每次操作会选择一个区间[l,r],将第l个字母到第r个字母各重复一次,插入到该字母的后面。
例如,对于字符串"abcd",若选择区间[2,3]进行操作,字符串将变成"abbccd"
游游将进行q次操作。她想知道,q次操作结束后,最终的字符串是什么样子?
输入描述:
第一行输入两个正整数n和q,分别代表字符串长度和操作次数。
第二行输入一个仅由小写英文字母组成的字符串,代表初始的字符串。
接下来的q行,每行输入两个正整数l,r,代表操作的区间。
1≤n≤1000
1≤q≤10
1≤l≤r≤106
保证每次操作时,r不大于当前的字符串长度。
输出描述:
一个字符串,代表所有操作结束后形成的字符串。
示例1
输入
6 2
abcdef
2 4
3 6
输出
abbbccccdddef
说明
第一次操作后,字符串变成abbccddef
第二次操作后,字符串变成abbbccccdddef
解题思路
本来想用迭代器对string
类型进行计算的,但是发现每当我插入一个字母之后,【下标index】会相应的改变,这着实令人头大。
接下来看看我找出来的规律。
每当我对一个字母进行重复的时候,那么后边的第二个字母需要操作时,我的迭代器iterator就要跨两格~
⭕️ 注意读题。字符串后边的q
行代表的【操作区间】,是个闭区间。并且代表的是【第几个 ~ 第几个】
如示例中,第一行是2 4
代表的是重复 第2个~第4个字母
相应的下标应该-1
。
结合上述两个条件
1️⃣ 跨两格 2️⃣ 下标-1
。
我们就知道应该在那里开始重复字母了。
✌️起始字母的下标是【l-1
】,第一个字母不需要跨两格,步长应为2*0
第二个字母下标需要跨两格,则为l-1+2*1
,以此类推…
【其实就是一个等差数列~】
❓如何控制走多少个两格?
闭区间
⟺
\iff
⟺你要操作多少个字母。【r-l+1
】
利用for
循环控制即可。
🌰拿示例说事儿
第一步的2 4
,将第2个到第4个字母翻倍。
原字符串:【abcdef
】
利用j
控制3个字母的翻倍位置position。
第2个字母b
的下标index是【1 = 2(l)-1+2*0(j)
】,翻倍后是abbcdef
;
第3个字母c
的下标应该是【3 = 2(l)-1+2*1(j)
】,翻倍后是abbccdef
;
第4个字母d
的下标是【5 = 2(l)-1+2*2(j)
】,翻倍后是abbccddef
,符合题意!
代码详情
#include <iostream>
#include<string>
using namespace std;
int main() {
int a, b;
cin >> a >> b;
string s;
cin >> s;
int l,r;
string::iterator it;
for(int i=0;i<b;i++){
cin >> l >> r;
// it=s.begin()+l-1;//第l个字母
// cout << "初始 = "<< s << endl;
for(int j=0;j<=r-l;j++){
//会导致下标不对应!!
// cout << "当前字母 = "<<*(s.begin()+l+(2*j-1)) << endl;
s.insert(s.begin()+l+(2*j-1),*(s.begin()+l+(2*j-1)));
}
// cout << s<<endl;
}
cout << s;
}