找规律题
如果首尾如果不交,那么不一样的位数就是需要变换的次数。
如果首尾相交,似乎比较复杂,所以找找规律。
假设字符串是这样的(上下是同一个字符串,只是为了方便描述首尾部分而分开画的),要让蓝色的首尾部分相同:
因为是一个字符串,所以虚线部分相同。
即,下图中红色方框部分相同。
因为蓝色首尾部分相同,所以有:
即虚线部分相同:
而此时,我们又可以得到这个虚线部分相同:
最终,不断重复这个过程,我们将蓝色部分划分成了一个个循环节:
从第一步可以看出,这个循环节的长度是n-k
所以,只要保证蓝色部分是以n-k为长度循环即可满足条件。
代码如下:
#include<iostream>
#include<string.h>
using namespace std;
char s[1005];
int main()
{
int c;
int k;
cin>>c;
while(c--)
{
cin>>s>>k;
int n=strlen(s);
int count=0;
if(2*k<=n)
{
for(int i=0;i<k;++i)
count+=(s[i]!=s[n-k+i])?1:0;
}else
{
int len=n-k;
for(int i=0;i<len;++i)
{
int num4[4]={};
int max=0;
for(int j=i;j<n;j+=len)
{
if(s[j]=='A')
num4[0]++;
else if(s[j]=='T')
num4[1]++;
else if(s[j]=='C')
num4[2]++;
else if(s[j]=='G')
num4[3]++;
}
for(int k=0;k<4;++k)
{
count+=num4[k];
if(max<num4[k])
max=num4[k];
}
count-=max;
}
}
cout<<count<<endl;
}
}