Description
2015年广东工业大学ACM校赛要来~(≧▽≦)/~辣辣辣,作为校赛的出题人之一,GG想出了一道水题来考考大家。相信小伙伴们都学过字符串匹配,于是字符串匹配的水题就诞生辣!GG给出了一段长度为N的大写字母序列,现在他要你修改这一段字母序列,使得这段字母序列上最前面的K个字母组成的序列与最后面的K个字母组成的序列一一匹配。
例如对于序列“ATUUUUAC”和K = 2,可以通过将第二个字母修改为“C”,使得最前面的两个字母与最后面的两个字母都为“AC”,当然 还存在其他的修改方法,现在GG要求你求出要使字符串匹配至少需要修改多少个字母。
Input
有T组数据输入。(T <= 100)
每组数据只有两行,第一行为一个字符串,第二行为一个正整数K,字符串的长度不会超过1000,且至少为1。(1 <= K <= N)。
Output
对于每组数据输出至少需要修改的字母数量
Sample Input
2
ATUUUUAC
2
ATACGTCT
6
Sample Output
1
3
HINT
分三种情况
1.k = 字符串长度 那么什么都不用改,结果就是0
2.k < 字符串长度/2 则没有交叉部分,算出两部分不匹配的个数就是答案
3.k >= 字符串长度/2 且 k < 字符串长度。
这种情况有重叠部分。
可以计算出。哪几个字母相关
如第二组样例ATACGTCT 6
则s[0], s[2], s[4], s[6]相关,那么要改变最少,算出每一组相关字符中最多的字符个数,则都把这组的别的字符改成这个字符。
最后把每组要改的结果加起来即可。
1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 #include <string> 5 #include <algorithm> 6 using namespace std; 7 string s; 8 int Letter[30]; 9 int main(){ 10 int T, k, sum; 11 scanf("%d", &T); 12 while(T--){ 13 cin>>s; 14 sum = 0; 15 scanf("%d", &k); 16 17 if(k <= s.size()/2){ 18 for(int i = 0; i < k; i++){ 19 if(s[i] != s[s.size()-k+i]) sum++; 20 } 21 } 22 else if(k == s.size()) sum = 0; 23 else if(k > s.size()/2 && k < s.size()){ 24 int d = s.size() - k; 25 for(int i = 0; i < s.size()- k; i++){ 26 memset(Letter, 0, sizeof(Letter)); 27 int cnt = 0, max = 0; 28 for(int j = i; j < s.size(); j += d){ 29 Letter[s[j] - 'A']++; 30 cnt++; 31 } 32 for(int k = 0; k < 26; k++){ 33 if(Letter[k] >= max) max = Letter[k]; 34 } 35 sum += cnt - max; 36 } 37 } 38 printf("%d ",sum); 39 } 40 41 42 return 0; 43 }