解题思路:
注意事项:
参考代码:
#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分
1 人评分
C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:
一点编程也不会写的:零基础C语言学练课程
解决困扰你多年的C语言疑难杂症特性的C语言进阶课程
从零到写出一个爬虫的Python编程课程
只会语法写不出代码?手把手带你写100个编程真题的编程百练课程
信息学奥赛或C++选手的 必学C++课程
蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程
手把手讲解近五年真题的蓝桥杯辅导课程
发表评论 取消回复