我已经醉了。出题人卡精度卡常数都是未知生物啊!!!
已经无心写题解,来个详细的~~~“网址”吧: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);
}