您的位置:首页 > 编程语言 > Go语言

【NOIP模拟题】【暴力求解法】【JOI】2016.11.14第二题 愉快的logo设计 题解

2016-11-14 16:16 393 查看
愉快的logo设计(B.c/cpp/pas/in/out)

(Time Limit:1s Memory Limit:256MB)

【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

我们的所求的那个字符串是几乎确定的,那么我们就改变开头来暴力搞他。(30%)

记录J、O、I的前缀和,再暴力。(100%)

附代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<vector>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<string>
#include<iomanip>
#include<ctime>
#include<climits>
#include<cctype>
#include<algorithm>
#define LL long long
#ifdef WIN32
#define AUTO "%I64d"
#else
#define AUTO "%lld"
#endif

using namespace std;

const int maxxx = 1048580;
int k,len,tot=1e9+7;
int J[maxxx*2],O[maxxx*2],I[maxxx*2],f[12];
char a[maxxx*2];

template <class T> inline void read(T &xx)
{
xx = 0;
T flag = 1;
char ch = (char)getchar();
while(ch<'0' || ch>'9')
{
if(ch == '-') flag = -1;
ch = (char)getchar();
}
while(ch>='0' && ch<='9')
{
xx = (xx<<1) + (xx<<3) + ch - '0';
ch = (char)getchar();
}
xx *= flag;
}

void init()
{
read(k);
scanf("%s",a);
len = strlen(a);
for (int i = len; i <= len*2-1; i++) a[i] = a[i-len];
len = strlen(a);
}

void work()
{
f[0] = 1;
for(int i = 1; i <= 10; i++)
f[i] = f[i-1] * 4;
for(int i = 0; i < len; i++)
{
J[i] += J[i-1];
O[i] += O[i-1];
I[i] += i[I-1];
if(a[i] == 'J') J[i]++;
if(a[i] == 'O') O[i]++;
if(a[i] == 'I') I[i]++;
}
for(int i=0;i<len/2;i++)
{
int ans = 1, h = i;
for(int j = k - 1; j >= 0; j--)
{
for(int s = 0; s <= 2; s++)
{
if(h != 0)
{
if(s == 0) ans += J[h+f[j]-1] - J[h-1];
if(s == 1) ans += O[h+f[j]-1] - O[h-1];
if(s == 2) ans += I[h+f[j]-1] - I[h-1];
h += f[j];
}
else
{
if(s == 0) ans += J[h+f[j]-1];
if(s == 1) ans += O[h+f[j]-1];
if(s == 2) ans += I[h+f[j]-1];
h += f[j];
}
}
}
tot = min(tot, len/2-ans);
}
}

int main()
{
freopen("B.in","r",stdin);
freopen("B.out","w",stdout);
init();
work();
printf("%d",tot);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: