题目链接:https://www.nowcoder.com/acm/contest/16/D
时间限制:1秒
空间限制:131072K
题目描述
FST是一名可怜的小朋友,他很强,但是经常fst,所以rating一直低迷。
但是重点在于,他真的很强!他发明了一种奇特的加密方式,这种加密方式只有OIer才能破解。
这种加密方式是这样的:对于一个01串,他会构造另一个01串,使得原串是在新串中没有出现过的最短的串。
现在FST已经加密好了一个串,但是他的加密方式有些BUG,导致没出现过的最短的串不止一个,他感觉非常懊恼,所以他希望计算出没出现过的最短的串的长度。
但是重点在于,他真的很强!他发明了一种奇特的加密方式,这种加密方式只有OIer才能破解。
这种加密方式是这样的:对于一个01串,他会构造另一个01串,使得原串是在新串中没有出现过的最短的串。
现在FST已经加密好了一个串,但是他的加密方式有些BUG,导致没出现过的最短的串不止一个,他感觉非常懊恼,所以他希望计算出没出现过的最短的串的长度。
输入描述:
一行,一个01串。长度≤105
输出描述:
一行,一个正整数,表示没有出现过的最短串的长度。
示例1
输入
100010110011101
输出
4
解析:一共才1e5个01串,最大长度不超过13, (2^13 - 1) * 13 = 106483 > 1e5,咱可以建立字典树,然后BFS搜最短长度,第一个不能到的深度就是答案
借鉴大牛博客:http://www.cnblogs.com/SCaryon/p/7702224.html
代码:
#include<bits/stdc++.h>
using namespace std;
char str[100005];
typedef struct node
{
struct node *n[2];
node()
{
memset(n, 0, sizeof(n));
}
}Q, *T;
T root = new node();
typedef pair<T, int> P;
void Creat(char *s)
{
T p = root;
for(int i = 0; s[i] && i <= 13; i++)
{
int id = s[i] - '0';
if(p->n[id] == NULL)
{
p->n[id] = new node();
}
p = p->n[id];
}
}
int Find()
{
T p = root;
queue<P> q;
q.push(make_pair(p, 1));
while(!q.empty())
{
P cur = q.front(); q.pop();
T x = cur.first;
int k = cur.second;
for(int i = 0; i < 2; i++)
{
if(x->n[i] != NULL)
q.push(make_pair(x->n[i], k+1));
else return k;
}
}
return 13;
}
void F(T S)
{
if(S == NULL) return ;
for(int i = 0; i < 2; i++)
{
if(S->n[i])
F(S->n[i]);
}
delete S;
S = NULL;
}
int main()
{
scanf(" %s", str);
for(int i = 0; str[i]; i++)
{
Creat(&str[i]);
}
printf("%d\n", Find());
F(root);
return 0;
}