Description
F S T FST FST是一名可怜的小朋友,他很强,但是经常 f s t fst fst,所以 r a t i n g rating rating一直低迷。
但是重点在于,他真的很强!他发明了一种奇特的加密方式,这种加密方式只有 O I e r OIer OIer才能破解。
这种加密方式是这样的:对于一个 01 01 01串,他会构造另一个 01 01 01串,使得原串是在新串中没有出现过的最短的串。
现在 F S T FST FST已经加密好了一个串,但是他的加密方式有些 B U G BUG BUG,导致没出现过的最短的串不止一个,他感觉非常懊恼,所以他希望计算出没出现过的最短的串的长度。
Input
一行,一个 01 01 01串。长度 ≤ 1 0 5 \le 10^5 ≤105
Output
一行,一个正整数,表示没有出现过的最短串的长度。
Sample Input
100010110011101
Sample Output
4
Solution
长度为 i i i的不同串有 2 i 2^i 2i个,而该串至多只有 ∣ s ∣ − i + 1 |s|-i+1 ∣s∣−i+1个长度为 i i i的子串,故没出现过的长度最短的串的长度不会超过 18 18 18,那么我们找出该串所有长度不超过 18 18 18的串,将每个串转化为二进制表示为该串的数字打上标记,那么没打上标记的最短串长度即为答案
Code
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn=1000005;
char s[maxn];
int f[maxn];
int main()
{
scanf("%s",s+1);
int n=strlen(s+1);
for(int i=1;i<=n;i++)
{
int res=s[i]-'0';
for(int j=1;j<=18&&i+j<=n;j++)
{
f[res]=1;
res=2*res+s[i+j]-'0';
}
}
for(int i=0;;i++)
if(!f[i])
{
int num=0;
while(i)i/=2,num++;
printf("%d\n",num);
break;
}
return 0;
}