1. 程式人生 > >【NOIp模擬賽】String Master

【NOIp模擬賽】String Master

sin for style clu amp ans idt int span

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\n",ans); fclose(stdin); fclose(stdout); return 0; }

【NOIp模擬賽】String Master