题意:给出一个长为 n 的,由字母表中前 k 个小写字母组成的字符串 s.求一个长度为m的字符串,要求该串也只能由字母表前 k 个小写字母组成,且其不能是 s 的子串.
(题目指出一定有解)
方法一:在判重时采用这样的方法,想把原串中长度为m1的字串都求出hash值存入set中,然后从0开始寻找第一个未出现在set中的数,将其翻译成相应的字符串.
#include<iostream>
#include<cstring>
#include<cstdio>
#include<set>
using namespace std;
typedef long long ll;
const int N = 10010;
char s[N];
ll a[100];
set<ll>ss;
void print(int x,int m,int k)
{
if(m==0)
{
return ;
}
print(x/k,m-1,k);
printf("%c",x%k+'a');
}
int main(void)
{
int T,n,m,k;
scanf("%d",&T);
while(T--)
{
ss.clear();
scanf("%d%d%d",&n,&m,&k);
scanf("%s",s);
if(k==1)
{
for(int i=0;i<m;i++)
{
printf("%c",'a');
}
printf("\n");
}
else
{
int sum=k,tem=n;
int m1=1;
while(sum<=tem) //算出当有几个字符时可能有不重复的字串
{
m1++;
sum*=k;
tem--;
}
if(m1>m) m1=m;
a[0]=1;
for(int i=1;i<=m1;i++)
{
a[i]=a[i-1]*k;
}
ll ans=0;
for(int i=0;i<m1;i++)
{
ans=ans*k+s[i]-'a';
}
ss.insert(ans);
for(int i=m1;i<n;i++)
{
ans-=a[m1-1]*(s[i-m1]-'a');
ans=ans*k+s[i]-'a';
ss.insert(ans);
}
for(int i=0;;i++)
{
if(ss.find(i)==ss.end())
{
print(i,m1,k);
printf("\n");
break;
}
}
}
}
return 0;
}
方法二:在判重时采用这样的方法,想把原串中长度为m1的字串都求出hash值存入ss数组中,然后经过sort,unique得到的是有序的字串,扫一遍即可.
#include<iostream>
#include<cstring>
#include<cstdio>
#include<set>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N = 10010;
char s[N];
ll a[100];
ll ss[20000];
void print(int x,int m,int k)
{
if(m==0)
{
return ;
}
print(x/k,m-1,k);
printf("%c",x%k+'a');
}
int main(void)
{
int T,n,m,k;
scanf("%d",&T);
while(T--)
{
memset(ss,0,sizeof(ss));
scanf("%d%d%d",&n,&m,&k);
scanf("%s",s);
if(k==1)
{
for(int i=0;i<m;i++)
{
printf("%c",'a');
}
printf("\n");
}
else
{
int sum=k,tem=n;
int m1=1;
while(sum<=tem) //算出当有几个字符时可能有不重复的字串
{
m1++;
sum*=k;
tem--;
}
if(m1>m) m1=m;
a[0]=1;
for(int i=1;i<=m1;i++)
{
a[i]=a[i-1]*k;
}
ll ans=0;
for(int i=0;i<m1;i++)
{
ans=ans*k+s[i]-'a';
}
int pos=0;
ss[pos++]=ans;
for(int i=m1;i<n;i++)
{
ans-=a[m1-1]*(s[i-m1]-'a');
ans=ans*k+s[i]-'a';
ss[pos++]=ans;
}
sort(ss,ss+pos);
unique(ss,ss+pos);
for(int i=0;;i++)
{
if(ss[i]!=i)
{
print(i,m1,k);
printf("\n");
break;
}
}
}
}
return 0;
}