字符翻转
给你一个长度为N,且N为偶数的字符串
其只由两种字符组成,要么为“G"要么为”H“
现在希望更可能多的”G"处于偶数位置
可采取的操作是:
让字符串某个长度为偶数的前缀进行翻转,这个长度可以由你来确定.
所谓前缀就是从第1个字符开始到某个字符结束。
现在问:为达到目标,最少进行多少次翻转操作
Format
Input
第一行给出N
第二行给出字符串
N<=2e5
Output
如题
Samples
输入数据 1
14
GGGHGHHGHHHGHG
输出数据 1
1
Hint 翻转前只有4个“G"处于偶数位置
对前6个字符进行翻转后,得到HGHGGGHGHHHGHG
可使6个”G"处于偶数位置,没有比这个更多的了。
SOl
这个题还是有些意思的
字符只有两种G,H
位置也只有两种奇,偶。
于是对于输入的字符串,我们每2个位置做一次划分。
所以2个位置,每个位置上可放G,H,就有四种搭配
对于要调整的字符GH,如果它后面是GG这种情况即GHGG
我们调整GHGG,其实与调整GH是等价的,也就是说后面如果是GG,完全不要它的参与
如果它后面是HH这种情况即GHHH
我们调整GHHH,其实与调整GH是等价的,也就是说后面如果是HH,完全不要它的参与。
对于GH这种字符,是需要调整的,调整分成2种情况
第1种情况
GH后面是0个或多个GH,直接调整
第2种情况
形如:GHGH..........HG,最后面遇到了1个HG
也是一次调整完成
不妨设GH为1,HG为0
于是上面的例子就是11......0.
调整结束后变成00......0,
而事实上我们解决此题所要达到上最终状态就是从1个01相间的数列变成1个全0的数列
接下来讨论HG,也就是0这种情况
如果是单独的1个或多个HG,那是不要调整的
但如果后面来了个1,变成0001
我们会发现HG,调整1次变成GH
HGHG,调整1次变成GHGH
于是对于0001这种情况
就先将前面000变成111
然后再将所有的1,统一调整1次变成0000
接下来统计变化次数,可发现整理出来的字符串会变成
101010或010101这种形态
如果是
101010这种形态
我们从左扫到右,当某个字符与其右的不一样,则先变成右边的,于是变化如下
101010-->001010-->111010-->000010-->111110-->000000
一共是变化5次
如果是
010101这种形态,变化如下
010101-->110101-->000101-->111101-->000001-->111111-->00000
一共是变化6次
综合就是
从左扫到右,如果当前位与其右边那位不一样,就变化1次。
最后看下,最位一位如果1,则再加1次。
#include <bits/stdc++.h> using namespace std; int s[200001]; int main() { int a,n=1,sum=0,ans=0; char b,c; cin>>a; for(int i=1;i<=a/2;i++) { cin>>b>>c; if(b=='G'&&c=='H')s[++ans]=1; if(b=='H'&&c=='G')s[++ans]=0; } for(int i=1;i<=ans-1;i++) { if(s[i]!=s[i+1])sum++; } if(s[ans]==1)sum++; cout<<sum; return 0; }