Codeforces Round #630 (Div. 2) C. K-Complete Word(字符串)
Word ss of length nn is called kk -complete if
- ss is a palindrome, i.e. si=sn+1−isi=sn+1−i for all 1≤i≤n1≤i≤n ;
- ss has a period of kk , i.e. si=sk+isi=sk+i for all 1≤i≤n−k1≤i≤n−k .
For example, "abaaba" is a 33 -complete word, while "abccba" is not.
Bob is given a word ss of length nn consisting of only lowercase Latin letters and an integer kk , such that nn is divisible by kk . He wants to convert ss to any kk -complete word.
To do this Bob can choose some ii (1≤i≤n1≤i≤n ) and replace the letter at position ii with some other lowercase Latin letter.
So now Bob wants to know the minimum number of letters he has to replace to convert ss to any kk -complete word.
Note that Bob can do zero changes if the word ss is already kk -complete.
You are required to answer tt test cases independently.
The first line contains a single integer tt (1≤t≤1051≤t≤105 ) — the number of test cases.
The first line of each test case contains two integers nn and kk (1≤k<n≤2⋅1051≤k<n≤2⋅105 , nn is divisible by kk ).
The second line of each test case contains a word ss of length nn .
It is guaranteed that word ss only contains lowercase Latin letters. And it is guaranteed that the sum of nn over all test cases will not exceed 2⋅1052⋅105 .
For each test case, output one integer, representing the minimum number of characters he has to replace to convert ss to any kk -complete word.
4 6 2 abaaba 6 3 abaaba 36 9 hippopotomonstrosesquippedaliophobia 21 7 wudixiaoxingxingheclp
2 0 23 16
大意就是对于一个字符串,每一次操作能改变一个字符,问最少操作多少次能让这个字符串变成有长度为k循环节的回文串。
思路很好想,首先由对称性可知,每个子串也必须都是对称的,所以最终就是要把原字符串转化为k个完全相同的回文子串。让求最少操作次数,不妨对这n/k个长度为k的子串进行分析。每个子串的第i个位置和第k-i+1个位置要相同,所以统计每个子串在这些对称位置出现次数最多的字母,把其他字母转换为这些字母。比如样例的n=6 k=2 abaaba,子串为ab aa ba 在1位置a两次b一次,在2w位置a两次b一次,合计a4次b两次(因为在对称位置要相同,所以得合起来考虑)
ans+=n/k*2-num(出现最多的字母的次数)更新即可。
注意:注释掉的部分的写法会T,而且注意t=1e5的情况下不能memset。
#include <bits/stdc++.h> using namespace std; int n,k; char s[200005]; int main() { int t; cin>>t; while(t--) { scanf("%d%d",&n,&k); scanf("%s",s+1); int i,j; // int cnt[200005][26]={0}; // int mmax[200005]={0}; // for(i=1;i<=n;i+=k) // { // for(j=i;j<=i+k-1;j++) // { // cnt[j-i+1][s[j]-'a']++; // if(k%2!=0&&j-i+1==k/2+1) // { // if(cnt[j-i+1][s[j]-'a']>mmax[k/2+1]) mmax[k/2+1]=cnt[k/2+1][s[j]-'a']; // } // else // { // if(cnt[j-i+1][s[j]-'a']+cnt[k-j+i][s[j]-'a']>mmax[min(k-j+i,j-i+1)]) mmax[min(k-j+i,j-i+1)]=cnt[j-i+1][s[j]-'a']+cnt[k-j+i][s[j]-'a']; // } // } // } // int ans=0; // for(i=1;i<=k/2;i++) // { // // ans+=n/k*2-mmax[i]; // } // if(k%2!=0) // { // ans+=n/k-mmax[k/2+1]; // } // cout<<ans<<endl; int ans=0; for(i=1;i<=k/2;i++) { int a[26]={0}; for(j=1;j<=n;j+=k) { a[s[j+i-1]-'a']++; a[s[j+k-i]-'a']++; } int mmax=0; for(j=0;j<26;j++)mmax=max(mmax,a[j]); ans+=n/k*2-mmax; } if(k%2!=0) { int a[26]={0}; for(j=1;j<=n;j+=k) { a[s[j+k/2]-'a']++; } int mmax=0; for(j=0;j<26;j++)mmax=max(mmax,a[j]); ans+=n/k-mmax; } cout<<ans<<endl; } return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!