【NOIp模拟赛】String Master

Input file: master.in
Output file: master.out
Time limit: 1 seconds
Memory limit: 128 megabytes

所谓最长公共子串,比如串 A: “abcde”,串 B: “jcdkl”,则它们的最长公共子串为串 “cd”,即长度最长的字符串,且在两个串中都作为连续子串出现过。
给定两个长度都为 n 的字符串,对于字符串大师的你来说,求它们的最长公共子串再简单不过了。
所以现在你有 k 次修改机会,每次你可以选择其中某个串的某个位置,将其修改成任意字符。
你需要合理使用这 k 次修改机会,使得修改之后两个串的最长公共子串最长。相信对于字符串大师的你来说,这个问题也难不倒你。
Input
第一行包含两个整数 n; k,分别表示字符串的长度和修改次数。
第二行包含一个长度为 n 的仅由小写字符构成的字符串 S。
第三行包含一个长度为 n 的仅由小写字符构成的字符串 T。
Output
输出一行一个整数,即修改完毕之后两个串的最长公共子串的长度。
Examples

 

master.in master.out
5 0
abcde
jcdkl
2
5 2
aaaaa
ababa
5

Notes
对于 100% 的数据, 0 ≤ k ≤ n。

测试点编号 n k
1 = 5 = 0
2 = 10 = 0
3 = 10 = 0
4 = 10 = 1
5 = 10 = 1
6 = 100 100
7 = 150 150
8 = 200 200
9 = 250 250
10 = 300 300


分析

暴力和动规都可以写,时间复杂度都是O(n^3)。

代码

暴力枚举

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=300+5;
inline int read()
{
    int x=0,f=1; char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1; ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0'; ch=getchar();}
    return x*f;
}
int n,k,ans;
char a[maxn],b[maxn];
int main()
{
    freopen("master.in","r",stdin);
    freopen("master.out","w",stdout);
    n=read();k=read();
    scanf("%s%s",a+1,b+1);
    for(int i=1;i<=n;i++)
    for(int j=1;j<=n;j++)
    {
        int x=i,y=j,cnt=0;
        while(x<=n&&y<=n)
        {
            if(a[x]!=b[y]) cnt++;
            if(cnt>k) break;
            x++; y++;
        }
        ans=max(ans,x-i);
    }
    printf("%d
",ans);
    fclose(stdin); fclose(stdout);
    return 0;
}
    
欢迎转载,转载请注明出处!
原文地址:https://www.cnblogs.com/huihao/p/7470253.html