[ICPC 2024 Kunming I] 左移 2题解

题目描述

给定一个由小写字母组成的字符串,称该字符串是美丽的,若字符串中每一对相邻的字符都不相同。例如,icpc 和 kunming 是美丽的,但 hello 不是,因为它的第 3 个和第 4 个字符相同。

给定由小写英文字母组成的,长度为 n 的字符串 S=s0​s1​⋯sn−1​,令 f(S,d) 表示将 S 左移 d 次后获得的字符串。也就是说 f(S,d)=s(d+0)modn​s(d+1)modn​⋯s(d+n−1)modn​。

令 g(S,d) 表示将 f(S,d) 变得美丽的最小操作次数。每次操作中,您可以将 f(S,d) 中的任意一个字符改为任意小写字母。

找到一个非负整数 d 最小化 g(S,d),并输出这个最小化的值。

输入格式

有多组测试数据。第一行输入一个整数 T 表示测试数据组数。对于每组测试数据:

第一行输入一个仅由小写字母组成的字符串 s0​s1​⋯sn−1​(1≤n≤5×105)。

保证所有数据 n 之和不超过 5×105。

输出格式

每组数据输出一行一个整数,表示最小的 g(S,d)。

输入输出样例

输入 #1复制

3
abccbbbbd
abcde
x

输出 #1复制

2
0
0

说明/提示

对于第一组样例数据,考虑 d=5。有 f(S,5)= bbbdabccb。对于这个字符串,我们可以将它的第 2 个字符改成 x,并将它的第 8 个字符改成 y。这样字符串就会变成 bxbdabcyb,是一个美丽的字符串。

思路

贪心。

#include<bits/stdc++.h>
using namespace std;
long long t,n,k,a[1000006],m,b[1000006],c[1000006],d[1000006],lk=0,sd=0,wd=0,dd=0,uz=0,df=0,fk=0,as=0;
string s;
int main(){
	cin>>t;
    while(t--){
        cin>>s;
        n=s.size();
        for(int i=0;i<n;i++){
            a[i]=0;
        }
        as=0;
        for(int i=0;i<n;i++){
            if(i!=0&&s[i]==s[i-1]){
                a[as]++;
            }
            else{
            	as++;
                a[as]=1;
            }
        }
		if(s[0]==s[n-1]&&as!=1){
			a[1]+=a[as];
			as--;
		}
		lk=dd=0;
		if(as!=1){
			for(int i=1;i<=as;i++){
				if(a[i]%2==0){
					dd=1;
				}
				lk+=a[i]/2;
			}
		}
		else{
			for(int i=1;i<=as;i++){
				lk+=a[i]/2;
			}			
		}
        cout<<lk-dd<<endl;
    }
	return 0;
}

posted @ 2025-10-14 19:40  bz02_2023f2  阅读(11)  评论(0)    收藏  举报  来源