JZOJ 4295【NOIP2015模拟11.2】愉快的logo设计

Description

K理事长正在思考日本信息学奥林匹克竞赛选手的应援道具的logo问题。某天,K理事长突发奇想,想要设计一个用’J’,’O’,’I’三种文字环形排列的logo,意为希望选手能从JOI中收获快乐的意思。
(注:“环形地”在日文中的表述为“円状に”,“円”读作“en”,再加上“JOI”三个字即为“enjoy”……)
如下所示,对于任意非负整数k,我们定义标号为k的JOI序列Sk为:
·S0为’J’,’O’,’I’中任一字符构成的长度为1的字符串
·S[k+1]为最初4^k个字符都是’J’,接下来的4^k个字符都是’O’,接下来的4^k个字符都是’I’,最后4^k个字符是字符串Sk的长为4^(k+1)的字符串
现在,K理事长在纸上写下了由4^K个文字构成的一个环形字符串,字符串中每个字符都是’J’,’O’,’I’中的一个。K理事长想要修改一些文字,使得得到的字符串从某个起点开始顺时针读一圈后可以得到SK。在满足条件的情况下,要求修改的文字数量最少。

Analysis

很水的一道题。
因为有 4k 的连续一段相同字母,所以可以暴力,其实是按照4的幂倍增一下。预处理出目标串中的字母前缀出现次数。枚举开头,倍增到结尾,统计答案即可。

Code

#include<cstdio>
#include<cstring>
#include<algorithm>
#define fo(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
const int N=2097160;
int a[N],sum[3][N];
int main()
{
    freopen("logo.in","r",stdin);
    freopen("logo.out","w",stdout);
    int k,n=1,ans=N;
    char ch;
    scanf("%d\n",&k);
    fo(i,1,k) n*=4;
    fo(i,1,n)
    {
        fo(j,0,2) sum[j][i]=sum[j][i-1];
        scanf("%c",&ch);
        if(ch=='J') a[i]=0;
        else
        if(ch=='O') a[i]=1;
        else a[i]=2;
        sum[a[i]][i]++;
    }
    fo(i,n+1,n*2)
    {
        fo(j,0,2) sum[j][i]=sum[j][i-1];
        sum[a[i]=a[i-n]][i]++;
    }
    fo(i,n+1,n*2)
    {
        int tot=0;
        for(int j=i-n-1,k=n/4;k;k/=4)
        {
            tot+=sum[0][j+k]-sum[0][j],j+=k;
            tot+=sum[1][j+k]-sum[1][j],j+=k;
            tot+=sum[2][j+k]-sum[2][j],j+=k;
        }
        ans=min(ans,n-tot-1);
    }
    printf("%d",ans);
    fclose(stdin);fclose(stdout);
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值