GG的匹配串

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\n",sum);
39     }
40     
41     
42     return 0;
43 }

 

posted @ 2015-03-16 16:47  下周LGD该赢了吧  阅读(246)  评论(0编辑  收藏  举报