暴力求出每个单词的前缀数量 f [ i ]
那么如果我们要将这个单词排在第 L 位,前 L 1 位的方案数就是 ( f [ i ] 1 L 1 ) ,然后最后 n L 位就乱排。

#include <bits/stdc++.h>
using namespace std;
const int N=51;
const int p=1e9+7;
int n,f[N],C[N][N];

template<class T> void checkmin(T &a,const T &b) { if (b<a) a=b; } 
template<class T> void checkmax(T &a,const T &b) { if (b>a) a=b; }

class SimilarNames2 {
public:
    int count( vector <string> names, int L ) ;
};

int cmp(const string a,const string b){
    return a.size()<b.size();
}

int pd(string a,string b){
    for(int i=0;i<a.size();i++)
     if (a[i]!=b[i]) return 0;
    return 1;
}

void init(){
    for(int i=0;i<N;i++) C[i][0]=1;
    for(int i=1;i<N;i++)
     for(int j=1;j<=i;j++)
      C[i][j]=(C[i-1][j]+C[i-1][j-1])%p;
}

int SimilarNames2::count(vector <string> a, int L) {
    init();
    n=a.size();
    sort(a.begin(),a.end(),cmp);
    for(int i=0;i<n;i++){
        f[i]=1;
        for(int j=i-1;j>=0;j--)
         if (pd(a[j],a[i])){
            f[i]+=f[j];
            break;
         }
    }
    int ans=0;
    for(int i=0;i<n;i++)
     if (f[i]>=L) ans=(ans+C[f[i]-1][L-1])%p;
    for(int i=1;i<=n-L;i++) ans=1LL*ans*i%p;
    return ans;
}