Codeforces 603A - Alternative Thinking - [字符串找规律]

题目链接:http://codeforces.com/problemset/problem/603/A

 

题意:

给定一个 $01$ 串,我们“交替子序列”为这个串的一个不连续子序列,它满足任意的两个相邻的数字不相等。

现在,我们要对这个 $01$ 串的某一段非空连续子串进行反转操作,即将这一段上的所有 $0$ 变为 $1$,所有 $1$ 变为 $0$。

然后,求问进行了有且仅有一次的反转操作后,求该串的最长交替子序列的长度。

 

题解:

首先,对于一个 $01$ 串,对其进行压缩操作,即将所有连续的相同的数字压缩成一个数字,例如将 $10110011$ 可以压缩成 $10101$,然后得到的这个新的串就是一个交替子序列,并且是最长的那个。

而且不难发现,对于任何 $01$ 串,一次反转操作,可以使其最长交替子序列的长度增加 $0,1,2$:

1、本身就是一个交替子序列,增加 $0$。

2、包含一个“$00$”或者“$11$”,能增加 $1$。

3、包含超过一个的“$00$”或者“$11$”,能增加 $2$(注意这种情况,两个“$00$”重叠在一起得到“$000$”也算)。

换句话说,我们只要统计所有满足 $s[i]=s[i+1](i \in [1,n-1])$ 的 $i$ 的个数就能知道有多少个“$00$”或者“$11$”。

 

 

AC代码:

#include<bits/stdc++.h>
using namespace std;
int n;
string s;
int main()
{
    cin>>n>>s;

    int cnt=0;
    for(int i=0;i<n-1;i++) if(s[i]==s[i+1]) cnt++;

    int res=1, now=s[0];
    for(int i=1;i<n;i++) if(s[i]!=now) res++, now=s[i];

    if(cnt>=2) cout<<res+2<<endl;
    else if(cnt==1) cout<<res+1<<endl;
    else cout<<res<<endl;
}

 

上一篇:【thinking in java】ArrayList源码分析


下一篇:java学习第一阶段——面向对象