11.【题解】密码
题解
题意
- 给你几个字符串,给你密码长度,之后求出密码有多少种可能,其中如果方案数
,则需要按字典序输出所有方案。
题解
- 首先先求出每两个字符串的最大重合,记为
( ,在枚举时使用。(其实应该用。将字符串存到 ),但蒟蒻太蒻了,所以用祖传 循环解决 中,然后跑一遍 指针,之后用状压 先求出方案数。 中, 是当前节点的状态,也就是当前节点是哪个字母; 是当前在哪个节点, 是状态,也就是当前包含了那些字符串,用二进制的每一位来表示是否存在。 - 由于需要以字典序输出,所以将所有的解存起来,之后
一遍输出即可。
代码
代码不具有参考意义
#include<bits/stdc++.h> #define int long long #define N (1000010) #define I i #define Int int #define sort stable_sort using namespace std; namespace IO { #define ll long long const int MAX=1<<24; char buf[MAX],*p1=buf,*p2=buf; char obuf[MAX],*o=obuf; #define gc()(p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<24,stdin),p1==p2)?EOF:*p1++) //template<typename T> //inline T read() inline int read() { int x=0;bool f=1; char c=gc(); for(;c<48||c>57;c=gc())if(c=='-')f=0; for(;c>=48&&c<=57;c=gc())x=(x<<3)+(x<<1)+(c^48); return f?x:~x+1; } void print(ll x){if(x>9)print(x/10);*o++=(x%10)+'0';} void pit(ll x){if(x<0)*o++='-',x=~x+1;print(x);} void write(ll x,char ed){pit(x);*o++=ed;} void flush(){fwrite(obuf,o-obuf,1,stdout);} #undef ll } using IO::read;using IO::write;using IO::flush;using std::complex; inline int min(int x,int y){return y&((y-x)>>31)|x&(~(y-x)>>31);} inline int max(int x,int y){return x&((y-x)>>31)|y&(~(y-x)>>31);} inline void swap(int &x,int &y){int tmp=x;x=y;y=tmp;} long long n,m; void init_set() { #ifndef ONLINE_JUDGE freopen("in.txt","r",stdin); freopen("out.txt","w",stdout); #endif ios::sync_with_stdio(0); cin.tie(0),cout.tie(0); } namespace AC_Auto { string de[15]; int rel[15][15]; int cnt; struct aa { int son[27],nxt,ed; void init(){memset(son,0,sizeof(son)),nxt=ed=0;} }t[300010]; queue<int>q; void init() { for(int i(0);i<=cnt;++i)t[i].init(); cnt=0; } void insert(string d,int id) { int u(0),len(d.size()); for(int i(0);i<len;++i) { int v(d[i]-'a'); if(!t[u].son[v])t[u].son[v]=++cnt; u=t[u].son[v]; } t[u].ed=(1<<(id-1)); return; } void nxt_set() { for(int i(0);i<26;++i)if(t[0].son[i])q.push(t[0].son[i]); for(;q.size();) { int u(q.front());q.pop(); int Nxt(t[u].nxt); for(int i(0);i<26;++i) { int v(t[u].son[i]); if(!v){t[u].son[i]=t[Nxt].son[i];continue;} t[v].nxt=t[Nxt].son[i]; t[v].ed|=t[t[v].nxt].ed; //假如失配指针是个终止节点, //由于失配指针的前缀与当前字符串后缀相同, //所以实际上另一个字符串已经结束了。 q.push(v); } } } void solve(signed x,signed y) { int lx(de[x].size()); for(signed i(0);i<lx;++i) { bool ret=true; for(signed j(i);j<lx;++j) { if(de[y][j-i]^de[x][j]) {ret=false;break;} } if(ret)//这时就是最优解了。 {rel[x][y]=lx-i;return;} } rel[x][y]=0; } } using namespace AC_Auto; int dp[26][260][1030]; int a[15],fontanie,tp; string las[50]; signed main() { init_set(); cin>>m>>n; for(int i(1);i<=n;++i)cin>>de[i],insert(de[i],i); nxt_set(); for(signed i(1);i<=n;++i) for(signed j(1);j<=n;++j) if(i^j)solve(i,j); dp[0][0][0]=1; for(int i(1);i<=m;++i) for(int j(0);j<=cnt;++j) for(int l(0);l<(1<<n);++l) if(dp[i-1][j][l]) for(int k(0);k<26;++k) dp[i][t[j].son[k]][l|t[t[j].son[k]].ed]+=dp[i-1][j][l]; for(int i(0);i<=cnt;++i) fontanie+=dp[m][i][(1<<n)-1]; cout<<fontanie<<'\n'; if(fontanie>42)exit(0); switch(n) { case 1: cout<<de[1]; break; case 2: for(int i1(1);i1<=n;++i1) { for(int i2(1);i2<=n;++i2) { if(i1!=i2) { if(de[i1].size()+de[i2].size()-rel[i1][i2]!=m)continue; ++tp; for(int l(0);l<de[i1].size();++l) las[tp]+=de[i1][l]; for(int l(rel[i1][i2]);l<de[i2].size();++l) las[tp]+=de[i2][l]; las[tp]+='\n'; } } } break; case 3: for(int i1(1);i1<=n;++i1) { for(int i2(1);i2<=n;++i2) { if(i1!=i2) { for(int i3(1);i3<=n;++i3) { if(i1!=i3&&i2!=i3) { if(de[i1].size()+de[i2].size()+de[i3].size()-rel[i1][i2]-rel[i2][i3]!=m)continue; ++tp; for(int l(0);l<de[i1].size();++l) las[tp]+=de[i1][l]; for(int l(rel[i1][i2]);l<de[i2].size();++l) las[tp]+=de[i2][l]; for(int l(rel[i2][i3]);l<de[i3].size();++l) las[tp]+=de[i3][l]; las[tp]+='\n'; } } } } } break; case 4: for(int i1(1);i1<=n;++i1) for(int i2(1);i2<=n;++i2) if(i1!=i2) for(int i3(1);i3<=n;++i3) if(i1!=i3&&i2!=i3) for(int i4(1);i4<=n;++i4) if(i1!=i4&&i2!=i4&&i3!=i4) { if(de[i1].size()+de[i2].size()+de[i3].size()+de[i4].size()-rel[i1][i2]-rel[i2][i3]-rel[i3][i4]!=m)continue; ++tp; for(int l(0);l<de[i1].size();++l) las[tp]+=de[i1][l]; for(int l(rel[i1][i2]);l<de[i2].size();++l) las[tp]+=de[i2][l]; for(int l(rel[i2][i3]);l<de[i3].size();++l) las[tp]+=de[i3][l]; for(int l(rel[i3][i4]);l<de[i4].size();++l) las[tp]+=de[i4][l]; las[tp]+='\n'; } break; case 5: for(int i1(1);i1<=n;++i1) for(int i2(1);i2<=n;++i2) if(i1!=i2) for(int i3(1);i3<=n;++i3) if(i1!=i3&&i2!=i3) for(int i4(1);i4<=n;++i4) if(i1!=i4&&i2!=i4&&i3!=i4) for(int i5(1);i5<=n;++i5) if(i1!=i5&&i2!=i5&&i3!=i5&&i4!=i5) { if(de[i1].size()+de[i2].size()+de[i3].size()+de[i4].size()+de[i5].size()-rel[i1][i2]-rel[i2][i3]-rel[i3][i4]-rel[i4][i5]!=m)continue; ++tp; for(int l(0);l<de[i1].size();++l) las[tp]+=de[i1][l]; for(int l(rel[i1][i2]);l<de[i2].size();++l) las[tp]+=de[i2][l]; for(int l(rel[i2][i3]);l<de[i3].size();++l) las[tp]+=de[i3][l]; for(int l(rel[i3][i4]);l<de[i4].size();++l) las[tp]+=de[i4][l]; for(int l(rel[i4][i5]);l<de[i5].size();++l) las[tp]+=de[i5][l]; las[tp]+='\n'; } break; case 6: for(int i1(1);i1<=n;++i1) for(int i2(1);i2<=n;++i2) if(i1!=i2) for(int i3(1);i3<=n;++i3) if(i1!=i3&&i2!=i3) for(int i4(1);i4<=n;++i4) if(i1!=i4&&i2!=i4&&i3!=i4) for(int i5(1);i5<=n;++i5) if(i1!=i5&&i2!=i5&&i3!=i5&&i4!=i5) for(int i6(1);i6<=n;++i6) if(i1!=i6&&i2!=i6&&i3!=i6&&i4!=i6&&i5!=i6) { if(de[i1].size()+de[i2].size()+de[i3].size()+de[i4].size()+de[i5].size()+de[i6].size()-rel[i1][i2]-rel[i2][i3]-rel[i3][i4]-rel[i4][i5]-rel[i5][i6]!=m)continue; ++tp; for(int l(0);l<de[i1].size();++l) las[tp]+=de[i1][l]; for(int l(rel[i1][i2]);l<de[i2].size();++l) las[tp]+=de[i2][l]; for(int l(rel[i2][i3]);l<de[i3].size();++l) las[tp]+=de[i3][l]; for(int l(rel[i3][i4]);l<de[i4].size();++l) las[tp]+=de[i4][l]; for(int l(rel[i4][i5]);l<de[i5].size();++l) las[tp]+=de[i5][l]; for(int l(rel[i5][i6]);l<de[i6].size();++l) las[tp]+=de[i6][l]; las[tp]+='\n'; } break; case 7: for(int i1(1);i1<=n;++i1) for(int i2(1);i2<=n;++i2) if(i1!=i2) for(int i3(1);i3<=n;++i3) if(i1!=i3&&i2!=i3) for(int i4(1);i4<=n;++i4) if(i1!=i4&&i2!=i4&&i3!=i4) for(int i5(1);i5<=n;++i5) if(i1!=i5&&i2!=i5&&i3!=i5&&i4!=i5) for(int i6(1);i6<=n;++i6) if(i1!=i6&&i2!=i6&&i3!=i6&&i4!=i6&&i5!=i6) for(int i7(1);i7<=n;++i7) if(i1!=i7&&i2!=i7&&i3!=i7&&i4!=i7&&i5!=i7&&i6!=i7) { if(de[i1].size()+de[i2].size()+de[i3].size()+de[i4].size()+de[i5].size()+de[i6].size()+de[i7].size()-rel[i1][i2]-rel[i2][i3]-rel[i3][i4]-rel[i4][i5]-rel[i5][i6]-rel[i6][i7]!=m)continue; ++tp; for(int l(0);l<de[i1].size();++l) las[tp]+=de[i1][l]; for(int l(rel[i1][i2]);l<de[i2].size();++l) las[tp]+=de[i2][l]; for(int l(rel[i2][i3]);l<de[i3].size();++l) las[tp]+=de[i3][l]; for(int l(rel[i3][i4]);l<de[i4].size();++l) las[tp]+=de[i4][l]; for(int l(rel[i4][i5]);l<de[i5].size();++l) las[tp]+=de[i5][l]; for(int l(rel[i5][i6]);l<de[i6].size();++l) las[tp]+=de[i6][l]; for(int l(rel[i6][i7]);l<de[i7].size();++l) las[tp]+=de[i7][l]; las[tp]+='\n'; } break; case 8: for(int i1(1);i1<=n;++i1) for(int i2(1);i2<=n;++i2) if(i1!=i2) for(int i3(1);i3<=n;++i3) if(i1!=i3&&i2!=i3) for(int i4(1);i4<=n;++i4) if(i1!=i4&&i2!=i4&&i3!=i4) for(int i5(1);i5<=n;++i5) if(i1!=i5&&i2!=i5&&i3!=i5&&i4!=i5) for(int i6(1);i6<=n;++i6) if(i1!=i6&&i2!=i6&&i3!=i6&&i4!=i6&&i5!=i6) for(int i7(1);i7<=n;++i7) if(i1!=i7&&i2!=i7&&i3!=i7&&i4!=i7&&i5!=i7&&i6!=i7) for(int i8(1);i8<=n;++i8) if(i1!=i8&&i2!=i8&&i3!=i8&&i4!=i8&&i5!=i8&&i6!=i8&&i7!=i8) { if(de[i1].size()+de[i2].size()+de[i3].size()+de[i4].size()+de[i5].size()+de[i6].size()+de[i7].size()+de[i8].size()-rel[i1][i2]-rel[i2][i3]-rel[i3][i4]-rel[i4][i5]-rel[i5][i6]-rel[i6][i7]-rel[i7][i8]!=m)continue; ++tp; for(int l(0);l<de[i1].size();++l) las[tp]+=de[i1][l]; for(int l(rel[i1][i2]);l<de[i2].size();++l) las[tp]+=de[i2][l]; for(int l(rel[i2][i3]);l<de[i3].size();++l) las[tp]+=de[i3][l]; for(int l(rel[i3][i4]);l<de[i4].size();++l) las[tp]+=de[i4][l]; for(int l(rel[i4][i5]);l<de[i5].size();++l) las[tp]+=de[i5][l]; for(int l(rel[i5][i6]);l<de[i6].size();++l) las[tp]+=de[i6][l]; for(int l(rel[i6][i7]);l<de[i7].size();++l) las[tp]+=de[i7][l]; for(int l(rel[i7][i8]);l<de[i8].size();++l) las[tp]+=de[i8][l]; las[tp]+='\n'; } break; case 9: for(int i1(1);i1<=n;++i1) for(int i2(1);i2<=n;++i2) if(i1!=i2) for(int i3(1);i3<=n;++i3) if(i1!=i3&&i2!=i3) for(int i4(1);i4<=n;++i4) if(i1!=i4&&i2!=i4&&i3!=i4) for(int i5(1);i5<=n;++i5) if(i1!=i5&&i2!=i5&&i3!=i5&&i4!=i5) for(int i6(1);i6<=n;++i6) if(i1!=i6&&i2!=i6&&i3!=i6&&i4!=i6&&i5!=i6) for(int i7(1);i7<=n;++i7) if(i1!=i7&&i2!=i7&&i3!=i7&&i4!=i7&&i5!=i7&&i6!=i7) for(int i8(1);i8<=n;++i8) if(i1!=i8&&i2!=i8&&i3!=i8&&i4!=i8&&i5!=i8&&i6!=i8&&i7!=i8) for(int i9(1);i9<=n;++i9) if(i1!=i9&&i2!=i9&&i3!=i9&&i4!=i9&&i5!=i9&&i6!=i9&&i7!=i9&&i8!=i9) { if(de[i1].size()+de[i2].size()+de[i3].size()+de[i4].size()+de[i5].size()+de[i6].size()+de[i7].size()+de[i8].size()+de[i9].size()-rel[i1][i2]-rel[i2][i3]-rel[i3][i4]-rel[i4][i5]-rel[i5][i6]-rel[i6][i7]-rel[i7][i8]-rel[i8][i9]!=m)continue; ++tp; for(int l(0);l<de[i1].size();++l) las[tp]+=de[i1][l]; for(int l(rel[i1][i2]);l<de[i2].size();++l) las[tp]+=de[i2][l]; for(int l(rel[i2][i3]);l<de[i3].size();++l) las[tp]+=de[i3][l]; for(int l(rel[i3][i4]);l<de[i4].size();++l) las[tp]+=de[i4][l]; for(int l(rel[i4][i5]);l<de[i5].size();++l) las[tp]+=de[i5][l]; for(int l(rel[i5][i6]);l<de[i6].size();++l) las[tp]+=de[i6][l]; for(int l(rel[i6][i7]);l<de[i7].size();++l) las[tp]+=de[i7][l]; for(int l(rel[i7][i8]);l<de[i8].size();++l) las[tp]+=de[i8][l]; for(int l(rel[i8][i9]);l<de[i9].size();++l) las[tp]+=de[i9][l]; las[tp]+='\n'; } break; case 10: for(int i1(1);i1<=n;++i1) for(int i2(1);i2<=n;++i2) if(i1!=i2) for(int i3(1);i3<=n;++i3) if(i1!=i3&&i2!=i3) for(int i4(1);i4<=n;++i4) if(i1!=i4&&i2!=i4&&i3!=i4) for(int i5(1);i5<=n;++i5) if(i1!=i5&&i2!=i5&&i3!=i5&&i4!=i5) for(int i6(1);i6<=n;++i6) if(i1!=i6&&i2!=i6&&i3!=i6&&i4!=i6&&i5!=i6) for(int i7(1);i7<=n;++i7) if(i1!=i7&&i2!=i7&&i3!=i7&&i4!=i7&&i5!=i7&&i6!=i7) for(int i8(1);i8<=n;++i8) if(i1!=i8&&i2!=i8&&i3!=i8&&i4!=i8&&i5!=i8&&i6!=i8&&i7!=i8) for(int i9(1);i9<=n;++i9) if(i1!=i9&&i2!=i9&&i3!=i9&&i4!=i9&&i5!=i9&&i6!=i9&&i7!=i9&&i8!=i9) for(int i10(1);i10<=n;++i10) if(i1!=i10&&i2!=i10&&i3!=i10&&i4!=i10&&i5!=i10&&i6!=i10&&i7!=i10&&i8!=i10&&i9!=i10) { if(de[i1].size()+de[i2].size()+de[i3].size()+de[i4].size()+de[i5].size()+de[i6].size()+de[i7].size()+de[i8].size()+de[i9].size()+de[i10].size()-rel[i1][i2]-rel[i2][i3]-rel[i3][i4]-rel[i4][i5]-rel[i5][i6]-rel[i6][i7]-rel[i7][i8]-rel[i8][i9]-rel[i9][i10]!=m)continue; ++tp; for(int l(0);l<de[i1].size();++l) las[tp]+=de[i1][l]; for(int l(rel[i1][i2]);l<de[i2].size();++l) las[tp]+=de[i2][l]; for(int l(rel[i2][i3]);l<de[i3].size();++l) las[tp]+=de[i3][l]; for(int l(rel[i3][i4]);l<de[i4].size();++l) las[tp]+=de[i4][l]; for(int l(rel[i4][i5]);l<de[i5].size();++l) las[tp]+=de[i5][l]; for(int l(rel[i5][i6]);l<de[i6].size();++l) las[tp]+=de[i6][l]; for(int l(rel[i6][i7]);l<de[i7].size();++l) las[tp]+=de[i7][l]; for(int l(rel[i7][i8]);l<de[i8].size();++l) las[tp]+=de[i8][l]; for(int l(rel[i8][i9]);l<de[i9].size();++l) las[tp]+=de[i9][l]; for(int l(rel[i9][i10]);l<de[i10].size();++l) las[tp]+=de[i10][l]; las[tp]+='\n'; } break; } sort(las+1,las+1+tp); for(int i(1);i<=tp;++i) cout<<las[i]; return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】