CF1370E-Binary Subsequence Rotation

题意:

给定 \(0,1\) 构成的串 \(s,t\),若能通过 \(s\) 串旋转的方式,进行字母重排,让其变成 \(t\) 串,输出最小旋转次数,反之,则输出 \(-1\)
\(1≤n≤10^6\)

分析:

要想有解,肯定两个串中的 \(0,1\) 的个数要相等。
考虑把 \(s\) 串中和 \(t\) 串对应位置不相等的字符拿出组成一个新的 \(0,1\) 串,原过程就相当于不断地从该新的序列中拿出 \(01010101\)\(101010\) 形式的串,然后该序列不断的变小,直到长度为 \(0\)。可以用两个变量来存 \(0\)\(1\) 的个数,同时进行消除。

代码:

#include <bits/stdc++.h>
using namespace std;
const int N=1e6+5;
char s[N],t[N];
int main()
{
    int n,cnt1=0,cnt2=0,zero=0;
    scanf("%d",&n);
    scanf("%s%s",s+1,t+1);
    for(int i=1;i<=n;i++)
    {
        if(s[i]!=t[i])
        {
            if(s[i]=='0')
            {
                cnt1++,zero++;
                if(cnt2>0) cnt2--;//消除重复,一个0和一个1消除只要一次
            }
            else
            {
                cnt2++,zero--;
                if(cnt1>0) cnt1--;//消除重复,一个0和一个1消除只要一次
            }
        }
    }
    if(zero) printf("-1\n");
    else printf("%d\n",cnt1+cnt2);
    return 0;
}

另外看到了下面的代码,很精简,相当于是上面过程的压缩版。

#include <bits/stdc++.h>
using namespace std;
int main() {
    int n; string s, t; cin >> n >> s >> t;
    int zero = 0, mi = 0, mx = 0;
    for (int i = 0; i < n; i++) {
        if (s[i] != t[i]) {
            if (s[i] == '0') zero++; //zero > 0 是最长的连续为 0 的长度
            else zero--; //zero < 0 是最长的不被抵消的连续为 1 的长度
            mi = min(mi, zero);
            mx = max(mx, zero);
        }
    }
    cout << (zero == 0 ? mx - mi : -1);
}

参考博客1
参考博客2

猜你喜欢

转载自www.cnblogs.com/1024-xzx/p/13191221.html