#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<cmath>
#include<queue>
#include<vector>
#include<string>
using namespace std;
const int SIGMA_SIZE=26;
const int MAXNODE=100+20;
const int maxn=25+2;
const int maxm=10+2;
const int maxlen=1<<10;
typedef long long LL;
int AllState=0;
int idx[256];
void init()
{
for(int i=0;i<26;i++){
idx[i+'a']=i;
}
}
struct ACAutomata{
int ch[MAXNODE][SIGMA_SIZE];
int f[MAXNODE];
int val[MAXNODE];
int last[MAXNODE];
int sz;
LL dp[MAXNODE][maxn][maxlen];
void init()
{
memset(ch[0],0,sizeof(ch[0]));
memset(dp,-1,sizeof(dp));
sz=1;
}
void insert(char s[],int n,int v)
{
int u=0;
for(int i=0;i<n;i++){
int c=idx[s[i]];
if(!ch[u][c]){
memset(ch[sz],0,sizeof(ch[sz]));
val[sz]=0;
ch[u][c]=sz++;
}
u=ch[u][c];
}
val[u]|=v;
}
void getFail()
{
queue<int> que;
int u=0;
f[0]=0;
for(int c=0;c<SIGMA_SIZE;c++){
u=ch[0][c];
if(u){
f[u]=0;last[u]=0;
que.push(u);
}
}
while(!que.empty()){
int r=que.front();que.pop();
for(int c=0;c<SIGMA_SIZE;c++){
u=ch[r][c];
if(!u){
ch[r][c]=ch[f[r]][c];
continue;
}
que.push(u);
int v=f[r];
while(v&&!ch[v][c]){
v=f[v];
}
f[u]=ch[v][c];
val[u]|=val[f[u]];
}
}
}
LL dfs(int u,int len,int st)
{
if(dp[u][len][st]!=-1) return dp[u][len][st];
if(len==0){
if(st==AllState) return dp[u][len][st]=1;
else return dp[u][len][st]=0;
}
LL & ans=dp[u][len][st];
ans=0;
for(int i=0;i<SIGMA_SIZE;i++){
ans=ans+dfs(ch[u][i],len-1,st|val[ch[u][i]]);
}
return ans;
}
char resstr[maxn];
int cur=0;
vector<string> outstr;
void getstr(int u,int len,int st)
{
if(len==0){
outstr.push_back(string(resstr));
return;
}
for(int i=0;i<SIGMA_SIZE;i++){
LL tmp=dp[ch[u][i]][len-1][st|val[ch[u][i]]];
if(tmp!=-1&&tmp!=0){
resstr[cur++]=i+'a';
getstr(ch[u][i],len-1,st|val[ch[u][i]]);
cur--;
}
}
}
};
ACAutomata ac;
int N,M;
char str[maxm][maxm];
void solve();
int kase=0;
int main()
{
kase=0;
init();
while(~scanf("%d %d",&N,&M)){
if(N==0&&M==0) break;
kase++;
solve();
}
return 0;
}
void solve()
{
ac.init();
AllState=(1<<M)-1;
for(int i=0;i<M;i++){
scanf("%s",str[i]);
ac.insert(str[i],strlen(str[i]),1<<i);
}
ac.getFail();
LL ans=ac.dfs(0,N,0);
if(ans<=42){
printf("Case %d: %lld suspects\n",kase,ans);
memset(ac.resstr,0,sizeof(ac.resstr));
ac.outstr.clear();
ac.getstr(0,N,0);
ac.cur=0;
sort(ac.outstr.begin(),ac.outstr.end());
for(int i=0;i<ac.outstr.size();i++){
cout<<ac.outstr[i]<<endl;
}
}
else{
printf("Case %d: %lld suspects\n",kase,ans);
}
}
/*
10 2
hello
world
10 0
4 1
icpc
0 0
*/
UVALive-4126 AC自动机
最新推荐文章于 2017-10-18 19:44:36 发布