这题不难啊,别被吓到了.
观 察 一 下 一 个 串 a 想 要 左 移 相 等 和 右 移 相 等 需 要 满 足 什 么 条 件 。 观察一下一个串a想要左移相等和右移相等需要满足什么条件。 观察一下一个串a想要左移相等和右移相等需要满足什么条件。
显 然 如 果 移 动 后 i 位 置 相 等 , 那 么 左 移 前 是 i + 1 , 右 移 前 是 i − 1 显然如果移动后i位置相等,那么左移前是i+1,右移前是i-1 显然如果移动后i位置相等,那么左移前是i+1,右移前是i−1
即 a i − 1 = = a i + 1 , 也 可 以 写 成 a i = = a i − 2 即a_{i-1}==a_{i+1},也可以写成a_i==a_{i-2} 即ai−1==ai+1,也可以写成ai==ai−2
特 别 的 , a 1 = = a n − 1 , a 2 = = a n 特别的,a_1==a_{n-1},a_2==a_n 特别的,a1==an−1,a2==an
不 难 发 现 a i = = a i − 2 这 个 式 子 , 每 隔 两 个 单 词 就 要 相 等 不难发现a_i==a_{i-2}这个式子,每隔两个单词就要相等 不难发现ai==ai−2这个式子,每隔两个单词就要相等
所 以 如 果 串 是 偶 数 长 度 , 那 么 所 有 奇 数 位 置 要 相 等 , 偶 数 位 置 也 要 相 等 所以如果串是偶数长度,那么所有奇数位置要相等,偶数位置也要相等 所以如果串是偶数长度,那么所有奇数位置要相等,偶数位置也要相等
(如果你不是一眼能看出来,在纸上画一画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;
}
}
一起加油努力呀~