众所周知,CSL 最喜欢的密码是 ******。于是有一天……

CSL 的密码

为了改变这一点,他决定重新设定一个密码。于是他随机生成了一个很长很长的字符串,并打算选择一个子串作为新密码。他认为安全的密码长度至少为 m,那么他有多少种不同选择方式呢?两种方案不同,当且仅当选出的密码内容不同。
输入描述:
第一行有两个整数 n 和 m ,分别表示 CSL 随机生成的字符串长度和安全的密码的最短长度。

第二行有一个长度为 n 的只含小写字母的字符串 s 表示 CSL 随机生成的字符串。

1≤m≤n≤105

输出描述:
在一行输出一个整数,表示 CSL 能选择的方案数。

示例1
输入
9 1
abcabcabc
输出
24

备注:
除样例外,所有的测试数据的字符串的每个字符均从小写字母 a - z 等概率随机生成。

仔细研究了一下这道题,这道题确实存在一些坑点和不严谨的地方。
先放一下AC的代码

#include<bits/stdc++.h>
using namespace std;
#define ll long long
set<string>s;
int main()
{
    ll n, m,count=0;
    string a;
    cin >> n >> m >> a;
	ll sum = (n - m + 1)*(n - m + 2) / 2;
    for (int i = m; i <= min(n,15LL); i++)
    {
        for (int j = 0; i + j - 1 < n; j++)
        {
            string temp = a.substr(j, i);
            if (s.find(temp) != s.end())
                count++;
            else
				s.insert(temp);
        }
    }
    cout << sum - count << endl;
    return 0;
}

大体思路就是先利用公式,求出长度为N的字符串取出M长的子串能有多少种方法,之后再遍历,利用substr函数,把所有重复的记录一下,用总的减去重复的即为合格的。

但是,AC代码中有几个很乍一看很莫名其妙的地方,第一个是在外层循环处为什么i要小于min(n,15LL),这里就要看题目的备注了,所有字符串随机生成,这就意味着长度到达一定之后,重复子串出现的几率几乎可以忽略不计,像连续重复的串这种情况在出题者的眼中是不存在的,多测了几次只要长度大于等于8就可以忽略了,但不能长于15,否则会超时。

第二个是在内层循环中,不难看出,代码的思路是看看集合中是否已经有了temp子串,如果有就记录,最后输出的是总的减去重复的,根据set的性质,直接输出s.size()可以有一样的效果,这样岂不是多此一举。这里坑点还是在于备注的随机生成,因为根据随机生成的特点,我们将长度过长的字符串默认为没有重复,所以外层循环实际上只是遍历了整个字符串的一部分,用下面这一个代码可以测试一下,ans的值实际上是小于答案值的,就是因为遍历时只遍历了一部分,这一部分不能表示全部,但是用总的减去重复的就可以把缺的那一部分默认为合格,这样才能过

测试set
#include<bits/stdc++.h>
using namespace std;
const int MAXN = 130000;
#define ll long long
set<string>s[100];
int main()
{
    ll n, m,count=0,ans=0;
    string a;
    cin >> n >> m >> a;
    ll sum = (n - m + 1)*(n - m + 2) / 2;
    for (int i = m; i <= min(n,15LL); i++)
    {
        for (int j = 0; i + j - 1 < n; j++)
        {
            string temp = a.substr(j, i);
            if (s[i].find(temp) != s[i].end())
                count++;
            else 
			{
				s[i].insert(temp);
				cout<<temp<<endl;
			}
        }
        ans+=s[i].size();
    }
    cout<<ans<<endl;
    cout << sum - count << endl;
    return 0;
}

相关文章:

  • 2021-05-27
  • 2021-08-06
  • 2021-10-08
  • 2022-01-07
  • 2021-10-22
  • 2021-06-13
  • 2022-12-23
  • 2022-12-23
猜你喜欢
  • 2021-11-11
  • 2021-06-10
  • 2021-08-20
  • 2021-08-08
  • 2022-12-23
  • 2021-11-09
相关资源
相似解决方案