K-Complete Word CodeForces - 1332C(贪心)

Word s of length n is called k-complete if

s is a palindrome, i.e. si=sn+1−i for all 1≤i≤n;
s has a period of k, i.e. si=sk+i for all 1≤i≤n−k.
For example, “abaaba” is a 3-complete word, while “abccba” is not.

Bob is given a word s of length n consisting of only lowercase Latin letters and an integer k, such that n is divisible by k. He wants to convert s to any k-complete word.

To do this Bob can choose some i (1≤i≤n) and replace the letter at position i with some other lowercase Latin letter.

So now Bob wants to know the minimum number of letters he has to replace to convert s to any k-complete word.

Note that Bob can do zero changes if the word s is already k-complete.

You are required to answer t test cases independently.

Input
The first line contains a single integer t (1≤t≤105) — the number of test cases.

The first line of each test case contains two integers n and k (1≤k<n≤2⋅105, n is divisible by k).

The second line of each test case contains a word s of length n.

It is guaranteed that word s only contains lowercase Latin letters. And it is guaranteed that the sum of n over all test cases will not exceed 2⋅105.

Output
For each test case, output one integer, representing the minimum number of characters he has to replace to convert s to any k-complete word.

Example
Input
4
6 2
abaaba
6 3
abaaba
36 9
hippopotomonstrosesquippedaliophobia
21 7
wudixiaoxingxingheclp
Output
2
0
23
16
Note
In the first test case, one optimal solution is aaaaaa.

In the second test case, the given word itself is k-complete.
唉,挺简单的一道题目给整复杂了。。
思路:根据题目要求,我们可以推断出,给定的字符串,每k位就是一个回文字符串。这样的话,我们就考虑这k位的字符串。对于这k位的回文字符串,我们要考虑对称的位置字符的数量,例如第一个样例来说,abaaba,第一位a有2个,b有1个;第二位a有2个,b有1个。因为第一位和第二位是对称的,所以我们要合起来考虑,a一共有4个,b一共有2个,a的数量更多,因此这些位置要替换成a。思路就是这样,实现的方式有很多。但是不要盲目的memset,因为有可能超时。
代码如下:

#include<bits/stdc++.h>
#define ll long long
using namespace std;

const int maxx=2e5+100;
int cnt[maxx][27];
string s;
int n,k;

inline void init()
{
	for(int i=0;i<k;i++) memset(cnt[i],0,sizeof(cnt[i]));
}
inline void dfs(int u,int flag)
{
	if(u>=n) return ;
	cnt[flag][s[u]-'a']++;
	dfs(u+k,flag);
}
int main()
{
	int t;
	scanf("%d",&t);
	while(t--)
	{
		scanf("%d%d",&n,&k);
		cin>>s;
		init();
		for(int i=0;i<k;i++) dfs(i,i);
		int l=0,r=k-1;
		int ans=0,_max=0;
		while(l<=r)//这样写就不用把奇数的情况单独拿出来考虑了。
		{
			if(l==r)
			{
				_max=0;
				for(int i=0;i<26;i++) _max=max(_max,cnt[l][i]);
				ans+=_max;
				break;
			}
			else
			{
				_max=0;
				for(int i=0;i<26;i++) _max=max(_max,cnt[l][i]+cnt[r][i]);
				ans+=_max;
				l++,r--;
			}
		}
		cout<<n-ans<<endl;
	}
	return 0;
}

努力加油a啊,(o)/~

发布了617 篇原创文章 · 获赞 64 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/starlet_kiss/article/details/105305534