BZOJ1704. [Usaco2007 Mar]Face The Right Way 自动转身机

传送门

把状态看成 $01$,把序列状态差分,那么每次一个区间翻转即为差分序列两边翻转,最终状态就是差分值全为 $0$

对于每个差分值不为 $0$ 的位置,我们一定要把它翻转,而差分值为 $0$ 的位置一定不能翻转,从左到右扫一遍贪心翻转就行

枚举所有 $K$  即可

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
typedef long long ll;
inline int read()
{
    int x=0,f=1; char ch=getchar();
    while(ch<'0'||ch>'9') { if(ch=='-') f=-1; ch=getchar(); }
    while(ch>='0'&&ch<='9') { x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); }
    return x*f;
}
const int N=1e4+7;
int n,a[N],b[N],c[N],ans,cnt;
bool check(int K)
{
    for(int i=1;i<=n+1;i++) c[i]=b[i]; cnt=0;
    for(int i=1;i<=n+1;i++)
    {
        if(!c[i]) continue;
        if(i+K>n+1) return 0;
        c[i]=0; c[i+K]^=1; cnt++;
    }
    return 1;
}
int main()
{
    n=read(); char ch[7];
    for(int i=1;i<=n;i++)
        scanf("%s",ch),a[i]=(ch[0]=='B');
    for(int i=1;i<=n+1;i++) b[i]=a[i-1]^a[i];
    for(int i=n;i>=1;i--) if(check(i)) { ans=i; break; }
    printf("%d %d
",ans,cnt);
    return 0;
}
原文地址:https://www.cnblogs.com/LLTYYC/p/11410810.html