解题思路:

注意事项:

参考代码:

#include <cstdio>

#include <algorithm>

#include <iostream>

#include <cmath>

#include <cstring>

#include <stack>

#include <queue>

#include <set>

#include <map>

#include <vector>

#include <sstream>

#include <string.h>

using namespace std;

typedef long long ll;

const int inf=0x3f3f3f3f;

const ll mod=1000000007;

const ll N=25;

const double pai=3.14159265358979;

const int maxn2=1e9;

#define mem(a,b) memset(a,b,sizeof(a))

priority_queue<int,vector<int>,greater<int> >pq;

map<string,vector<int> >mp;

vector<int>v,ve;

map<string,vector<int> >::iterator it1;

int n,m,k,x;

string s,s1;

map<string,int>vis;

map<string,int>::iterator it;

ll ans,dp[105][105];

void solve()

{

   mem(dp,0);

   x=v.size();

   dp[0][0]=1;

   for(int i=1;i<=x;++i)

   {

       dp[i][0]=1;

       for(int j=1;j<=i;++j)

       {

           dp[i][j]=dp[i-1][j-1]*v[i-1]+dp[i-1][j];//状态转移方程

           dp[i][j]%=mod;

       }

   }

   ans+=dp[x][m];

   ans%=mod;

}

int main()

{

   scanf("%d %d %d",&n,&m,&k);

   for(int i=1;i<=n;++i)

   {

       cin >> s;

       vis.clear();//初始时默认为false

       for(int j=0;j+k<=s.size();++j)//以后再遇到截取字符串固定长度时,记得j+k<=s.size()

       {

           s1=s.substr(j,k);

           vis[s1]++;//先收集所有长度为k的子串,记录每个子串出现次数

       }

       for(it=vis.begin();it!=vis.end();++it)

           //first为键,second为值,map是红黑树结构,会自动对键的字典序排序

       {

           s=it->first;

           ve=mp[s];//取原来记录下的vector数组

           ve.push_back(it->second);//将新的出现次数插入数组尾部

           mp[s]=ve;

       }

   }

   for(it1=mp.begin();it1!=mp.end();++it1)

   {

       v=it1->second;

       if(v.size()<m)continue;//明显不满足条件,提前剪枝

       solve();

   }

   printf("%lld\n",ans);

   return 0;

}


点赞(0)
 

0.0分

1 人评分

C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:

一点编程也不会写的:零基础C语言学练课程

解决困扰你多年的C语言疑难杂症特性的C语言进阶课程

从零到写出一个爬虫的Python编程课程

只会语法写不出代码?手把手带你写100个编程真题的编程百练课程

信息学奥赛或C++选手的 必学C++课程

蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程

手把手讲解近五年真题的蓝桥杯辅导课程

评论列表 共有 0 条评论

暂无评论