题意:
给定一个由A~H 8种字符组成,长度不超过1000000的字符串。问在这个字符串的最短的不存在的连续子串。若存在多个最短连续子串,输出字典序最
小的一个。
思路:可以知道当长度为7时,8^7已经比1e6长了,所以只要枚举答案就行了,然后枚举到某个长度k时,把字符串中所有长度为k的子串哈希成一个
int,然后在看0-8^k-1中是否有未出现的,如果有 就是答案。
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<stack>
using namespace std;
const int maxn = 1e6+5;
int fac[10];
char str[maxn];
bool vis[maxn];
bool solve(int k)
{
memset(vis, 0, sizeof(vis));
int len = strlen(str);
int tmp = 0;
for(int i = 0; i < k; i++)
tmp = tmp*8+str[i]-'A';
vis[tmp] = 1;
for(int i = k; i < len; i++)
{
tmp = tmp%fac[k-1];
tmp = tmp*8+str[i]-'A';
vis[tmp] = 1;
}
int p = 0;
while(vis[p]) p++;
if(p < fac[k])
{
for(int i = k-1; i >= 0; i--)
{
printf("%c", p/fac[i]+'A');
p %= fac[i];
}
puts("");
return 1;
}
return 0;
}
int main(void)
{
fac[0] = 1;
for(int i = 1; i < 10; i++)
fac[i] = fac[i-1]*8;
int t;
cin >> t;
while(t--)
{
scanf(" %s", str);
int p = 1;
while(!solve(p)) p++;
}
return 0;
}