题目链接: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; }