字符翻转

 

给你一个长度为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;
}

  

posted @ 2022-09-11 12:06  我微笑不代表我快乐  阅读(104)  评论(0编辑  收藏  举报