1528;匹配字符串(平顶山学院)

来源:互联网 发布:linux 下载工具 编辑:程序博客网 时间:2024/04/28 04:36
1528: 匹配字符串
题目描述
2015 年广东工业大学ACM校赛要来~\(≧▽≦)/~辣辣辣,作为校赛的出题人之一,GG想出了一道水题来考考大家。相信小伙伴们都学过字符串匹配,于是字符 串匹配的水题就诞生辣!GG给出了一段长度为N的大写字母序列,现在他要你修改这一段字母序列,使得这段字母序列上最前面的K个字母组成的序列与最后面的 K个字母组成的序列一一匹配。 
例如对于序列“ATUUUUAC”和K = 2,可以通过将第二个字母修改为“C”,使得最前面的两个字母与最后面的两个字母都为“AC”,当然 还存在其他的修改方法,现在GG要求你求出要使字符串匹配至少需要修改多少个字母。


输入
有T组数据输入。(T <= 100) 
每组数据只有两行,第一行为一个字符串,第二行为一个正整数K,字符串的长度不会超过1000,且至少为1。(1 <= K <= N)。

输出
对于每组数据输出至少需要修改的字母数量

样例输入
2
ATUUUUAC
2
ATACGTCT
6
样例输出
1
3

题目代码:
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int main()
{
    int num,len,m,i,b[26],j;
    char s[1000];
    scanf("%d",&num);
    while(num--)
    {
        int mmin=0;
        getchar();  //用于接收输入num后的那个空格
        scanf("%s",s); //输入字符串
        scanf("%d",&m); //前m个字符与后m个字符相同
        len=strlen(s);//测字符串长度
        if(m<=len/2)//如果m小于或等于字符串长度的一半的话,那么我只用比较前m个与后m个有几个字符不同,就是答案
        {
            for(i=0;i<m;i++)
                if(s[i]!=s[len+i-m])
                    mmin++;
            printf("%d\n",mmin);
        }
        else//这个比较麻烦,因为如果m>len/2时,许多字母是绑定在一起的
        {
            int t=len-m;
            for(i=0;i<m;i++)//前m个字符
            {
                j=i; 
                int sum1=0;
                memset(b,0,sizeof(b)); //每从一个字母开始,都将b数组置为0,代表从这个字母开始走,模拟出一条路
                while(1)
                {

                    if(s[j]!='1')//如果我这个位置没有走过
                    {
                        b[s[j]-'A']++; //选择一条路,并统计这条路中遇到的各个字母的个数
                        s[j]='1';    //标记为1,代表该位置考虑过了
                        sum1++;//与第i个字母绑定在一起的字母总个数
                    }
                    j=j+t; //下一个与第i个字母相关联的字母
                    if(j>len-1)//如果超过字符串的长度,代表所有与第i个字母相关联的字母都找完了
                        break;
                }
                sort(b,b+26);//排序,求与第I个字母绑定的所有字母中那个字母最多
                mmin=mmin+(sum1-b[25]); //就等于与第I个字母绑定的字母个数减去某个字母个数最多,就是最少的修改次数,
            }
            printf("%d\n",mmin);
           }
    }
    return 0;
}
 
0   1   2   3   4   5   6   7   
A   T   A  C   G   T  C   T


A   T   A   C   G   T  C   T
0    1   2   3   4   5  6   7

按照循环
当i=0时,
要修改的为0  2  4  6   A A G C这条路的长度为4,字母A最多,所以不修改字母A,将其他两个字母修改为字母A,需要路的长度-某个字母个数的最大值。
当i=1时
要修改的为1   3   5   7他们是相互绑定的。T C  T  T,字母T最多,所以将其他与字母T不一样的字母都变为T,修改的次数最少,这条路的长度为4
字母T最多是3个,那么要修改有4-3=1;
当i=2时
2  4  6 都已经考虑过了
当i=3时
3 5 7绑定也都考虑过了
........
0 0