ZOJ 4060 - Flippy Sequence - [思惟题][2018 ACM-ICPC Asia Qingdao Regional Problem C]

题目连接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=4060ios

 

题意:c++

给出两个 $0,1$ 字符串 $S,T$,如今你有两次对 $S$ 做区间翻转($0 \rightarrow 1,1 \rightarrow 0$)的操做,spa

用四元组 $(l_1,r_1,l_2,r_2)$ 表示,表明第一次翻转区间 $[l_1,r_1]$,第二次翻转区间 $[l_2,r_2]$。3d

问你有多少个四元组能够使得 $S=T$。code

 

题解:blog

把 $S$ 尽量少地分割成若干个子串。若某一子串和相应区间的 $T$ 同样,记做 $B$;反之,则记做 $A$。ci

所以若 $A$ 的数量大于两个,就不可能经过区间翻转两次使得 $S=T$,所以 $A$ 最可能是两个。字符串

分类讨论:get

  1. $A$ 有 $0$ 个,即整个$S$ 可表示为 $B$,任意翻转两次相同区间 $[i,j]$ 便可。整个 $1 \sim |S|$ 能够有 $|S| + (|S|-1) + \cdots + 1 = \frac{|S|(|S|+1)}{2}$。
  2. $A$ 有 $1$ 个,即$S$ 可表示为 $(B)A(B)$。若两边都没有 $B$,则能够将 $A$ 分红两个部分 $[l,m],[m+1,r]$ 分别翻转,考虑 $m$ 取值的可能有 $2 \times (|A|-1)$ 种;若两侧都有 $B$,即 $BAB$,则应在前面那种基础上,再算上,在某一侧的 $B$ 中挑选一个左端点,再以 $A$ 的右端点为区间右端点,这样一来有 $2 \times |B|$ 种选择。二者加起来即 $2 \times (|A|-1+|B|) = 2 \times (|S|-1)$。
  3. $A$ 有 $2$ 个,即$S$ 可表示为 $(B)ABA(B)$。只能有三种翻法:①ABA,B;②AB,BA;③A,A。所以即 $2 \times 3 = 6$ 种可能性。

 

AC代码:string

#include<bits/stdc++.h>
using namespace std;
int n;
string s,t;
int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    int T;
    cin>>T;
    while(T--)
    {
        cin>>n>>s>>t;
        int cnt=0;
        for(int i=0;i<n;i++) {
            if((i==0 || s[i-1]==t[i-1]) && s[i]!=t[i]) cnt++;
        }
        if(cnt>2) cout<<"0\n";
        else if(cnt==2) cout<<"6\n";
        else if(cnt==1) cout<<(2*n-2)<<'\n';
        else cout<<((long long)n*(n+1)/2)<<'\n';
    }
}
相关文章
相关标签/搜索