正解:$dp$+$AC$自动机+搜索

解题报告:

传送门$QwQ$

首先显然先建个$AC$自动机,然后考虑设$f_{i,j,k}$表示长度为$i$,现在在$AC$自动机的第$j$个位置,已经表示出来的串的状态为$k$的方案数,直接转移就好.

然后考虑输出方案.首先一定不存在可以随便填的位置.

挺显然的随便说下昂,首先如果有一个可以随便填的位置,就有26种可能.然后可以给这个位置和字符串交换位置,就至少有2种可能,这时候就已经至少有$2\times 26=52$了,所以一定不存在可以随便填的位置.

所以直接$O(!n)$爆搜$QwQ$,$over$

因为爆搜真的很麻烦,所以我直接开了个$vector$在$dp$转移的时候顺便记了下方案.

但是挺容易$MLE$的,所以我把第一维滚了下.

然后还有一个注意点是每次转移完之后没用的$vector$清空下不然真的$MLE$到飞起$kk$

#include<bits/stdc++.h>
using namespace std;
#define il inline
#define gc getchar()
#define ll long long
#define ri register int
#define rb register bool
#define rc register char
#define rp(i,x,y) for(ri i=x;i<=y;++i)
#define my(i,x,y) for(ri i=x;i>=y;--i) const int N=100+10,M=(1<<10)+10;
int len,n,nod_cnt,tot,nw=1,pre;
ll f[2][N][M],ans;
bool vis[N];
char s[N];
vector<string>as[2][N][M],an;
struct node{int to[27],zt,fail;}nod[N]; il int read()
{
rc ch=gc;ri x=0;rb y=1;
while(ch!='-' && (ch>'9' || ch<'0'))ch=gc;
if(ch=='-')ch=gc,y=0;
while(ch>='0' && ch<='9')x=(x<<1)+(x<<3)+(ch^'0'),ch=gc;
return y?x:-x;
}
il void insert(ri num)
{
scanf("%s",s+1);ri l=strlen(s+1),nw=0;
rp(i,1,l)
{
if(!nod[nw].to[s[i]-'a'])nod[nw].to[s[i]-'a']=++nod_cnt;
nw=nod[nw].to[s[i]-'a'];
}
nod[nw].zt=1<<num;
}
il void build()
{
queue<int>Q;
rp(i,0,25)if(nod[0].to[i])Q.push(nod[0].to[i]);
while(!Q.empty())
{
ri nw=Q.front();Q.pop();
rp(i,0,25)
if(nod[nw].to[i])Q.push(nod[nw].to[i]),nod[nod[nw].to[i]].fail=nod[nod[nw].fail].to[i];
else nod[nw].to[i]=nod[nod[nw].fail].to[i];
nod[nw].zt|=nod[nod[nw].fail].zt;
}
} signed main()
{
//freopen("4045.in","r",stdin);freopen("4045.out","w",stdout);
len=read();n=read();rp(i,1,n)insert(i-1);build();tot=(1<<n)-1;
f[0][0][0]=1;as[0][0][0].push_back("");
rp(i,1,len)
{
rp(j,0,nod_cnt)
{
rp(k,0,tot)
{
if(f[pre][j][k])
{
rp(t,0,25)
{
ri nwzt=k|nod[nod[j].to[t]].zt;
f[nw][nod[j].to[t]][nwzt]+=f[pre][j][k];
if(f[nw][nod[j].to[t]][nwzt]<=42)
{
ri sz=as[pre][j][k].size();
rp(tt,0,sz-1)as[nw][nod[j].to[t]][nwzt].push_back(as[pre][j][k][tt]+(char)(t+'a'));
}
}
}
f[pre][j][k]=0;if(!as[pre][j][k].empty())as[pre][j][k].clear();
}
}
nw^=1;pre^=1;
}
nw^=1;
rp(i,0,nod_cnt)
{
ans+=f[nw][i][(1<<n)-1];
if(ans<=42){ri sz=as[nw][i][(1<<n)-1].size();rp(j,0,sz-1)an.push_back(as[nw][i][(1<<n)-1][j]);}
}
printf("%lld\n",ans);if(ans>42)return 0;
sort(an.begin(),an.end());rp(i,0,ans-1)cout<<an[i]<<endl;
return 0;
}

随机推荐

  1. oracle函数 sysdate

    [功能]:返回当前日期. [参数]:没有参数,没有括号 [返回]:日期 [示例]select sysdate  hz from dual; 返回:2008-11-5

  2. epoll简介(二)

    一:多路复用的举例 以一个生活中的例子来解释: 假设你在大学中读书,要等待一个朋友(数据)来访(要读),而这个朋友只知道你在A号楼(socket集合),但是不知道你具体住在哪里,于是你们约好了在A号楼 ...

  3. chrome谷歌浏览器怎么清除指定网站cookie

    https://jingyan.baidu.com/article/fa4125aced30cc28ac709230.html 在使用电脑的情况下,由于到部分网站的cookie的问题导致的部分功能失效 ...

  4. Python 2.X 版本 600行入门基础

    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 3 ...

  5. 20182019-acmicpc-asia-dhaka-regional F .Path Intersection 树链剖分

    直接进行树链剖分,每次对路径区间内的所有点值+1,线段树进行维护,然后查询线段树的最大值的个数!!! 查询线段树区间最大值个数,可以先维护区间和,在维护区间最值,如果区间和等于区间最值乘以区间长度,那 ...

  6. Android教程-03 常见布局的总结

    常见的布局 视频建议采用超清模式观看, 欢迎点击订阅我的优酷 Android的图形用户界面是由多个View和ViewGroup构建出来的.View是通用的UI窗体小组件,比如按钮(Button)或者文 ...

  7. Element-ui学习笔记2

    1.Button按钮 <el-button> type属性可以修改按钮主题 type='text'时为文字按钮 plain,round,circle可以修改按钮样式,plain为朴素按钮, ...

  8. 使C# WebApi返回Json

    找到Global.asax文件,在Application_Start()方法中添加一句: protected void Application_Start() { AreaRegistration.R ...

  9. H3C ACL包过滤显示与调试

  10. Innodb_large_prefix

    innodb_large_prefix Prefixes, defined by the length attribute, can be up to 767 bytes long for InnoD ...