我已经醉了。出题人卡精度卡常数都是未知生物啊!!!
已经无心写题解,来个详细的~~~“网址”吧:http://wyfcyx.is-programmer.com/posts/78632.html
我的代码是被卡精度的,我可以附上数据生成器。
不要交我的代码,代码仅供参考思想。
代码:
#include <queue> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define N 80 #define T 26 #define inf 0x3f3f3f3f using namespace std; char s[7][17]; int len[7],n,m,p; bool able[7]; int check_sonstring(int a,int b) // check whether a is son of b { int i,j,fix; for(i=1;i<=len[b]-len[a]+1;i++) { for(j=0;j<len[a]&&s[a][j+1]==s[b][i+j];j++); if(j>=len[a])return len[a]==len[b]?-1:1; } return 0; } void check_string() { int i,j,k; scanf("%d%d%d",&n,&m,&p); for(i=1;i<=n;i++)scanf("%s",s[i]+1),len[i]=strlen(s[i]+1); for(i=1;i<=n;i++)for(j=1;j<=n;j++)if(i!=j) { k=check_sonstring(i,j); if(!k)continue; if(k>0)able[j]=1; if(k<0&&i<j)continue; } } struct MRX { long double x[N][N]; }Ini,Trs,I,Std;// 初始矩阵、转移矩阵、空矩阵、标准矩阵 int length; MRX Mul(const MRX &a,const MRX &b) { MRX C=I; for(int i=0;i<=length;i++) for(int j=0;j<=length;j++) for(int k=0;k<=length;k++) C.x[i][j]=C.x[i][j]+b.x[i][k]*a.x[k][j]; return C; } MRX Power(MRX x,int p) { MRX ret=Std; while(p) { if(p&1)ret=Mul(ret,x); x=Mul(x,x),p>>=1; } return ret; } struct ACAUTO { int son[N][T],root,cnt; bool end[N]; void insert(int id) { int i,x=root,alp; for(i=1;i<=len[id];i++) { alp=s[id][i]-'a'; if(!son[x][alp])son[x][alp]=++cnt; x=son[x][alp]; } end[x]=true; } queue<int>q; int fail[N]; void build_fail() { while(!q.empty())q.pop(); int i,u,v; q.push(root); while(!q.empty()) { u=q.front(),q.pop(); for(i=0;i<p;i++) { if(end[u])son[u][i]=son[root][i]; else if(v=son[u][i]) { if(u==root)fail[v]=0; else fail[v]=son[fail[u]][i]; q.push(v); } else son[u][i]=son[fail[u]][i]; } } } void build_matrix() { int i,j,k; Ini.x[0][0]=(long double)1.0; for(i=0;i<=cnt;i++) for(j=0;j<p;j++) Trs.x[son[i][j]][i]=Trs.x[son[i][j]][i]+(long double)1.0/(long double)p; cnt++; Trs.x[cnt][cnt]=(long double)1.0; for(i=0;i<cnt;i++)if(end[i]) Trs.x[cnt][i]=(long double)1.0; for(i=0;i<=cnt;i++)Std.x[i][i]=(long double)1.0; length=cnt; } }ac; int main() { freopen("test.in","r",stdin); check_string(); int i,j,k; for(i=1;i<=n;i++)if(able[i]==0)ac.insert(i); ac.build_fail(); ac.build_matrix(); MRX temp=Power(Trs,m+1); MRX final=Mul(Ini,temp); long double ans;ans=final.x[length][0]; // for(i=0;i<length;i++)if(ac.end[i])ans=ans+final.x[i][0]; double Ans=ans; printf("%lf",Ans); }