P10810 【MX-S2-T1】变 解题报告

【MX-S2-T1】变

题目描述

已知一个仅由小写英文字母构成的字符串 \(s\)

每次操作时,你可以任意选择 \(s\) 中的一个字符,并将它修改为任意小写英文字母。

你可以按任意顺序对其进行不超过 \(k\) 次操作,以最小化 \(s\)严格循环节的长度。当然,不进行操作也是可以的。

请输出在进行完所有操作后,最小的可能的 \(s\) 的严格循环节的长度。

一个字符串 \(t\) 被称为 \(s\) 的严格循环节,当且仅当 \(s\) 可以通过将 \(t\) 重复若干次来构造。

例如:maimaimai 的严格循环节,dxdx 的严格循环节。但 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;
}
posted @ 2025-01-13 14:32  vanueber  阅读(17)  评论(0)    收藏  举报