C. Good String(规律,连通块)

这题不难啊,别被吓到了.

观 察 一 下 一 个 串 a 想 要 左 移 相 等 和 右 移 相 等 需 要 满 足 什 么 条 件 。 观察一下一个串a想要左移相等和右移相等需要满足什么条件。 a

显 然 如 果 移 动 后 i 位 置 相 等 , 那 么 左 移 前 是 i + 1 , 右 移 前 是 i − 1 显然如果移动后i位置相等,那么左移前是i+1,右移前是i-1 i,i+1,i1

即 a i − 1 = = a i + 1 , 也 可 以 写 成 a i = = a i − 2 即a_{i-1}==a_{i+1},也可以写成a_i==a_{i-2} ai1==ai+1,ai==ai2

特 别 的 , a 1 = = a n − 1 , a 2 = = a n 特别的,a_1==a_{n-1},a_2==a_n ,a1==an1,a2==an

不 难 发 现 a i = = a i − 2 这 个 式 子 , 每 隔 两 个 单 词 就 要 相 等 不难发现a_i==a_{i-2}这个式子,每隔两个单词就要相等 ai==ai2,

所 以 如 果 串 是 偶 数 长 度 , 那 么 所 有 奇 数 位 置 要 相 等 , 偶 数 位 置 也 要 相 等 所以如果串是偶数长度,那么所有奇数位置要相等,偶数位置也要相等 ,,

(如果你不是一眼能看出来,在纸上画一画n=8的情况,就是分奇数和偶数两个连通块)

如 果 串 是 奇 数 , 假 设 n = 7 \color{Red}如果串是奇数,假设n=7 ,n=7

那 么 a 1 = = a 6 , a 2 = = a 7 , a 3 = = a 1 , a 4 = = a 2 , a 5 = = a 3 那么a_1==a_6,a_2==a_7,a_3==a_1,a_4==a_2,a_5==a_3 a1==a6,a2==a7,a3==a1,a4==a2,a5==a3

a 6 = = a 4 , a 7 = = a 5 a_6==a_4,a_7==a_5 a6==a4,a7==a5

可以发现这7个字母构成一个连通块,7个字母全部都要相等

算法就很显然了

先 假 定 满 足 条 件 的 最 长 串 是 奇 数 , 找 出 现 次 数 最 多 的 那 个 字 母 即 可 先假定满足条件的最长串是奇数,找出现次数最多的那个字母即可 ,

若 最 长 串 是 偶 数 , 枚 举 奇 数 位 置 和 偶 数 位 置 应 该 放 的 字 母 , 然 后 去 找 最 长 串 若最长串是偶数,枚举奇数位置和偶数位置应该放的字母,然后去找最长串 ,,

找到最长串后,要删掉的字母就是原长度-符合要求的最长序列

#include <bits/stdc++.h>
using namespace std;
int t,vis[11];
char a[200009];
int run(int q,int w,int n)
{
	char qq=q+'0',ww=w+'0';
	int ok=0,temp=0;
	for(int i=1;i<=n;i++)
	{
		if( a[i]==qq&&ok==0 )	ok^=1;
		if( a[i]==ww&&ok==1 )	ok^=1,temp+=2;//^操作,0变1,1变0 
	}
	return temp;
}
int main()
{
	cin >> t;
	while( t-- )
	{	
		cin >> (a+1);
		int ans=0,n=strlen(a+1);
		memset(vis,0,sizeof(vis));
		for(int i=1;i<=n;i++)
		{
			vis[ a[i]-'0' ]++;
			ans=max(ans,vis[ a[i]-'0' ]);//奇数情况 
		}
		for(int i=0;i<=9;i++)
		for(int j=0;j<=9;j++)
		{
			if( i==j )	continue;
			ans=max(ans,run(i,j,n) );
		}
		cout << n-ans << endl;
	}
}

一起加油努力呀~

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值