CF-Round #630-div2-C题

CF-Round #630-div2-C题

C. K-Complete Word

传送门

这道题。贪心~
关于回文的~

今天下午录了一期视频10分钟上传到B站。结果我在等审核通过。等了一下午。。还是审核中。
求内心阴影面积

题目大意:给你一个字符串。题目定义了一个概念。
意思就是这个回文串还必须是由长度为k子回文串重复出现构成。
问要构成这样的回文串最少需要修改多少个字符

贪心策略:
题目中都给定了k~我们就照他的意思模拟一下就可以啦
很明显长度为k的必须是回文串。
比如样例:
6 2
abaaba
长度为2:ab aa ba 这些也必须为回文串。并且要一样
怎样修改次数最少。
很明显啦
i从0开始
下标i, i + k, i + 2k, i + 3k…这些下标对应的字符肯定要相等。
然后i 对应的k - 1 - i也要对应相等。
我们只要记录每组出现次数最多的字符数目maxx。
然后用总数-maxx。
然后维护一下累加ans就行啦。
所以此前我们需要进行统计。
cnt[对应的下标(这里mod k 就行)][哪个字母(字母 - ‘a’)]++;

这里特别注意一下k的奇偶情况。(可以不讨论~)
我们最后累加的时候直接从0遍历到k-1。相当于算了两遍。肯定为偶数。最后/2就行。
(0对应k-1,到最后i到k-1的时候,k-1又会反过来对应0)所以算了两遍。
还是很好想的啦~

代码部分:

#include 
using namespace std;
const int N = 2e5 + 10;

int n, k;
string s;
int cnt[N][26];

int solve(int a, int b)
{
	int res = 0;
	int maxx = 0;
	for (int i = 0; i < 26; i++)
	{
		res += cnt[a][i] + cnt[b][i];
		maxx = max(maxx, cnt[a][i] + cnt[b][i]);
	}
	return res - maxx;
}

int main()
{
	int t;
	cin >> t;
	while (t--)
	{
		cin >> n >> k;
		cin >> s;
		for (int i = 0; i < k; i++)
		{
			for (int j = 0; j < 26; j++)
			{
				cnt[i][j] = 0;
			} 
		}
		for (int i = 0; i < n; i++)
		{
			cnt[i % k][s[i] - 'a']++;
		}
		int ans = 0;
		for (int i = 0; i < k; i++)
		{
			ans += solve(i, k - 1 - i);
		}
		cout << ans / 2<< endl;
	}
	return 0;
} 

你可能感兴趣的:(贪心,字符串)