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