NOIP模拟题——愉快的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。在满足条件的情况下,要求修改的文字数量最少。
【Input】
第一行一个正整数K,表示K理事长在纸上写下了一个长度为4^K的环状字符串。
第二行一个由’J’,’O’,’I’三个字符构成的长为4^K的字符串,表示纸上的环形字符串从某个起点出发顺时针阅读一圈得到的字符串。
【Output】
输出一行一个整数,表示修改文字数量的最小值。
【Sample Input】
2
JJOIJJOJOIOJOOOI
【Sample Output】
7
【HINT】

 


从○标记的位置顺时针阅读一圈得到“JJJJOOOOIIIIJOIJ”,满足S2的条件,且修改文字数达到最小值7。
【Data Constraint】
对于30%的数据,1<=K<=5
对于100%的数据,1<=K<=10

 

 

 

暴力找起点,每一次都看当前区间匹配的个数,然后跳到下一个小区间。到最后一个区间时,长度为1,最后一个点一定是匹配的,所以最后匹配数要加上1。由于每一次都找区间的匹配,且区间长度不同,所以考虑前缀和:将前i个的所有的J、O、I保存起来。由于题目描述说是一个环,所以可以处理成2条链拼接在一起,然后枚举。时间复杂度O(k*4^k)。

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cstring>
 4 using namespace std;
 5 const int maxn=1100000;
 6 char q[(maxn<<1)];
 7 int f[(maxn<<1)][5];
 8 int k;int ans=99999999;
 9 int so=0;
10 inline void solve(int x)
11 {
12     f[x][1]=f[x-1][1];
13     f[x][2]=f[x-1][2];
14     f[x][3]=f[x-1][3];
15     
16     
17     if(q[x]=='J')
18     f[x][1]++;
19     else if(q[x]=='O')
20     f[x][2]++;
21     else
22     f[x][3]++;
23     return ;
24 }
25 int main()
26 {
27     freopen("B.in","r",stdin);
28     freopen("B.out","w",stdout);
29     scanf("%d",&k);
30     int tot=(1<<(2*k));
31     for(int i=1;i<=tot;i++)
32     {
33         int c=getchar();
34         while(c!='J'&&c!='O'&&c!='I')c=getchar();
35         q[i]=c;q[i+tot]=c;
36     }
37     so=(1<<(2*k-2));
38     int qwer=so;
39     for(int i=1;i<=tot*2;i++)
40     solve(i);
41     for(int i=1;i<=tot;i++)
42     {
43         int qwe=0;
44         int temp=i;
45         so=qwer;
46         while(so)
47         {
48             qwe+=f[temp+so-1][1]-f[temp-1][1];
49             qwe+=f[temp+so*2-1][2]-f[temp+so-1][2];
50             qwe+=f[temp+so*3-1][3]-f[temp+so*2-1][3];
51             temp+=3*so;
52             so>>=2;
53         }
54         ans=min(ans,tot-qwe-1);
55     }
56     printf("%d",ans);
57     return 0;
58 }

 

posted @ 2016-11-14 16:48  deadshotz  阅读(552)  评论(0编辑  收藏  举报