hihoCoder#1052 基因工程
找规律题
如果首尾如果不交,那么不一样的位数就是需要变换的次数。
如果首尾相交,似乎比较复杂,所以找找规律。
假设字符串是这样的(上下是同一个字符串,只是为了方便描述首尾部分而分开画的),要让蓝色的首尾部分相同:
因为是一个字符串,所以虚线部分相同。
即,下图中红色方框部分相同。
因为蓝色首尾部分相同,所以有:
即虚线部分相同:
而此时,我们又可以得到这个虚线部分相同:
最终,不断重复这个过程,我们将蓝色部分划分成了一个个循环节:
从第一步可以看出,这个循环节的长度是n-k
所以,只要保证蓝色部分是以n-k为长度循环即可满足条件。
代码:
1 #include <iostream> 2 #include <cstring> 3 4 using namespace std; 5 6 int main() { 7 int T, K, N; 8 char str[1024]; 9 10 cin >> T; 11 while (T--) { 12 cin >> str; 13 cin >> K; 14 N = strlen(str); 15 int res = 0; 16 17 if (K * 2 <= N) { 18 for (int i = 0, j = N - K; j < N; j++, i++) 19 res += str[i] != str[j] ? 1 : 0; 20 cout << res << endl; 21 } 22 else { 23 int len = N - K; 24 for (int i = 0; i < len; i++) { 25 int count[4] = {0}; 26 for (int j = i; j < N; j += len) { 27 if (str[j] == 'A') 28 count[0]++; 29 else if (str[j] == 'T') 30 count[1]++; 31 else if (str[j] == 'C') 32 count[2]++; 33 else if (str[j] == 'G') 34 count[3]++; 35 } 36 int maximum = 0; 37 for (int j = 0; j < 4; j++) { 38 maximum = max(maximum, count[j]); 39 res += count[j]; 40 } 41 res -= maximum; 42 } 43 cout << res << endl; 44 } 45 } 46 47 return 0; 48 }