P10810 【MX-S2-T1】变 解题报告
【MX-S2-T1】变
题目描述
已知一个仅由小写英文字母构成的字符串 \(s\)。
每次操作时,你可以任意选择 \(s\) 中的一个字符,并将它修改为任意小写英文字母。
你可以按任意顺序对其进行不超过 \(k\) 次操作,以最小化 \(s\) 的严格循环节的长度。当然,不进行操作也是可以的。
请输出在进行完所有操作后,最小的可能的 \(s\) 的严格循环节的长度。
一个字符串 \(t\) 被称为 \(s\) 的严格循环节,当且仅当 \(s\) 可以通过将 \(t\) 重复若干次来构造。
例如:
mai是maimai的严格循环节,dx是dx的严格循环节。但ov不是ovo的严格循环节。
输入格式
第一行一个非负整数 \(k\)。
第二行一个字符串 \(s\),仅包含小写英文字母。
输出格式
一行一个整数,表示答案。
样例 #1
样例输入 #1
1
test
样例输出 #1
4
样例 #2
样例输入 #2
3
test
样例输出 #2
1
样例 #3
样例输入 #3
3
apollo
样例输出 #3
3
提示
【样例解释 #1】
可以证明:最多进行一次操作的情况下,严格循环节长度至少为 \(4\)。
【样例解释 #2】
可以通过 \(3\) 次操作,将 test 修改为 ssss,严格循环节长度为 \(1\)。
【数据范围】
本题采用捆绑测试。
- Subtask 0(17 pts):\(k = 0\),\(|s| \leq 6\)。
- Subtask 1(14 pts):\(k = 1\),\(|s| \leq 20\)。
- Subtask 2(16 pts):\(k = 1\),\(|s| \leq 500\)。
- Subtask 3(32 pts):\(k < |s| \leq 10^5\)。
- Subtask 4(21 pts): 无特殊限制。
对于所有测试数据,保证 \(0 \leq k < |s| \leq 10^6\),\(s\) 中仅包含小写英文字母。
2024.7.28:新增了一组 Hack 数据。
P10810 【MX-S2-T1】变
找到严格循环节的性质,可推出长度为 \(k\) 的循环节的性质,即相对应字符串(如 test 长度为 \(2\) 的两个字串为 te ,st)每一位最少修改次数为 \(\frac{size}{k}-p\) ,其中 \(size\) 为字符串长度,\(p\) 为出现最多字符次数。扫一遍 \(size\) 的因数即可。
注意慎用 \(STL\),\(100pts \rightarrow 79pts\) 血的教训。
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <string>
#include <unordered_map>
#include <cstring>
using namespace std;
int k;
string ss;
bool check(int l)
{
int chg=0;
for(int i=0;i<l;i++)
{
int ch[29]={0};
int sum=-1;
for(int j=i;j<ss.size();j+=l)
{
ch[ss[j]-'a']++;
}
for(int j=0;j<26;j++)
{
sum=max(sum,ch[j]);
}
chg+=(ss.size()/l)-sum;
}
return chg<=k;
}
int main()
{
cin>>k>>ss;
for(int i=1;i<=ss.size();i++)
{
if(ss.size()%i!=0) continue;
if(check(i))
{
cout<<i;
return 0;
}
}
return 0;
}

浙公网安备 33010602011771号