链接:https://ac.nowcoder.com/acm/contest/551/C
来源:牛客网
时间限制:C/C++ 2秒,其他语言4秒
空间限制:C/C++ 524288K,其他语言1048576K
64bit IO Format: %lld
题目描述
众所周知,CSL 最喜欢的密码是 ******。于是有一天……
为了改变这一点,他决定重新设定一个密码。于是他随机生成了一个很长很长的字符串,并打算选择一个子串作为新密码。他认为安全的密码长度至少为 m,那么他有多少种不同选择方式呢?两种方案不同,当且仅当选出的密码内容不同。
输入描述:
第一行有两个整数 n 和 m ,分别表示 CSL 随机生成的字符串长度和安全的密码的最短长度。
第二行有一个长度为 n 的只含小写字母的字符串 s 表示 CSL 随机生成的字符串。
1≤m≤n≤1051≤m≤n≤105
输出描述:
在一行输出一个整数,表示 CSL 能选择的方案数。
示例1
输入
复制
9 1 abcabcabc
输出
复制
24
备注:
除样例外,所有的测试数据的字符串的每个字符均从小写字母 a - z 等概率随机生成。
地址:https://ac.nowcoder.com/acm/contest/551/C
思路:这数据随机生成,还有这种骚操作orz ,这表明对于长度>10的子串就不需要考虑重复的情况了,概率几乎为0。。。
那么只要对长度<10的判断重复个数即可
Code:
#include<iostream>
#include<map>
using namespace std;
typedef long long LL;
LL n,m;
string str;
map<string,bool> imap;
int main()
{
ios::sync_with_stdio(false);
cin>>n>>m>>str;
LL ans=(n-m+1)*(n-m+2)/2;
string s;
for(int i=0;i<=n-m&&m<10;++i)
{
s.append(str.begin()+i,str.begin()+i+m);
if(imap[s]) --ans;
else imap[s]=true;
for(int j=i+m;j<n&&j-i<10;++j)
{
s+=str[j];
if(imap[s]) --ans;
else imap[s]=true;
}
s="";
}
cout<<ans<<endl;
return 0;
}