题解 CF1389C 【Good String】

简要题意:

对于一个字符串 t 1 , t 2 , ⋯   , t n t_1,t_2,\cdots,t_n t1,t2,,tn

我们定义它的右移为 t n , t 1 , ⋯   , t n − 1 t_n,t_1,\cdots,t_{n-1} tn,t1,,tn1

我们定义它的左移为 t 2 , t 3 , ⋯   , t 1 t_2,t_3,\cdots,t_{1} t2,t3,,t1

现在请问对于给出的一个字符串,最少删掉多少个字符才能是这个字符串的左移和右移完全相同?

我们来分析一下性质,比较一下右移和左移

右移: t n , t 1 , ⋯   , t n − 1 t_n,t_1,\cdots,t_{n-1} tn,t1,,tn1

左移: t 2 , t 3 , ⋯   , t 1 t_2,t_3,\cdots,t_{1} t2,t3,,t1

要使这 2 2 2 个东西相同就必须使得 t 2 = t n , t 1 = t 3 , ⋯   , t n − 1 = t 1 t_2=t_n,t_1=t_3,\cdots,t_{n-1}=t_1 t2=tn,t1=t3,,tn1=t1

我们举个具体的例子,假设 n = 8 n=8 n=8

右移: t 8 , t 1 , t 2 , t 3 , t 4 , t 5 , t 6 , t 7 t_8,t_1,t_2,t_3,t_4,t_5,t_6,t_7 t8,t1,t2,t3,t4,t5,t6,t7

左移: t 2 , t 3 , t 4 , t 5 , t 6 , t 7 , t 8 , t 1 t_2,t_3,t_4,t_5,t_6,t_7,t_8,t_1 t2,t3,t4,t5,t6,t7,t8,t1

显然, t 2 = t 4 = t 6 = t 8 t_2=t_4=t_6=t_8 t2=t4=t6=t8 t 1 = t 3 = t 5 = t 7 t_1=t_3=t_5=t_7 t1=t3=t5=t7

可以证明当 n n n 为偶数时,这个字符串的循环节必须为 2 2 2

我再来试试 n = 7 n=7 n=7

右移: t 7 , t 1 , t 2 , t 3 , t 4 , t 5 , t 6 t_7,t_1,t_2,t_3,t_4,t_5,t_6 t7,t1,t2,t3,t4,t5,t6

左移: t 2 , t 3 , t 4 , t 5 , t 6 , t 7 , t 1 t_2,t_3,t_4,t_5,t_6,t_7,t_1 t2,t3,t4,t5,t6,t7,t1

显然, t 1 = t 3 = t 5 = t 7 = t 2 = t 4 = t 6 t_1=t_3=t_5=t_7=t_2=t_4=t_6 t1=t3=t5=t7=t2=t4=t6\

可以证明当 n n n 为奇数时,这个字符串的循环节必须为 1 1 1

2 2 2 个东西笔者都试着证明了一下,有些麻烦,这里就不放了。

// Problem: C. Good String
// Contest: Codeforces - Educational Codeforces Round 92 (Rated for Div. 2)
// URL: https://codeforc.es/contest/1389/problem/C
// Memory Limit: 256 MB
// Time Limit: 2000 ms
// Powered by CP Editor (https://github.com/cpeditor/cpeditor)

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
template<typename T>inline void read(T &FF){
	T RR=1;FF=0;char CH=getchar();
	for(;!isdigit(CH);CH=getchar())if(CH=='-')RR=-1;
	for(;isdigit(CH);CH=getchar())FF=(FF<<1)+(FF<<3)+(CH^48);
	FF*=RR;
}
const int MAXN=2e5+10;
int s[11][2];
int work(){
	memset(s,0,sizeof(s));
	string st;cin>>st;
	int n=st.size(),ans=n;
	st=' '+st;
	for(int i=0;i<=9;i++){
		int s=0;
		for(int j=1;j<=n;j++)
			if(st[j]!=char(i+48))s++;
		ans=min(ans,s);
	}
	for(int i=0;i<=9;i++)
		for(int j=0;j<=9;j++){
			int s=0;
			for(int k=1;k<=n;k++){
				if(s%2==0){
					if(st[k]==char(i+48))s++;
				}else{
					if(st[k]==char(j+48))s++;
				}
			}
			if(s%2==1)s--;
			ans=min(ans,n-s);
		}
	cout<<ans<<endl;
	return 0;
}
int main(){
	int T;read(T);
	while(T--){
		//memset
		work();
	}
	return 0;
};
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值