【题目描述】
据说高二某班的物理有两本资料——《优化方案》和《高考总复习第一轮100课时》。做了一段时间后,就有同学发现这两本资料对应章节有很多内容都是相同的。于是有人就两本资料相应章节的相似程度做了些研究。
这里会给出S1和S2两个字符串(均由A-Z这26个字母组成)分别表示两本资料的题目类型,你要做的就是帮忙找到一个字符串S3,既是S1的子串又是S2的子串,并且最长(保证由所给的数据求出的S3是唯一的)。这里的S3即可以表示两本资料的相似度。
【输入格式】
输入文件book.in有两行。分别是S1和S2(S1和S2的长度均不超过200),表示两书题目类型。
【输出格式】
输出文件book.out包括两行。第一行是一个数字,为S3的长度。第二行为字符串S3,表示两书的相似度。
【样例输入】 【样例输出】
ACCGGTCGAGTGCGCGGAAGCCGGCCGAA 20
GTCGTTCGGAATGCCGTTGCTCTGTAAA GTCGTCGGAAGCCGGCCGAA
LCS的基本应用,最长公共子序列的记录开个二维数组,递归输出即可。
#include<iostream>
#include<iomanip>
#include<cstring>
#include<cmath>
#include<queue>
#include<algorithm>
#include<cstdio>
using namespace std;
int l1,l2;
int f[205][205],re[205][205],pre[205][205];
string s1,s2;
void out(int x,int y)
{
if(x==0||y==0) return;
out(re[x][y],pre[x][y]);
if(x-re[x][y]==1&&y-pre[x][y]==1) printf("%c",s1[x]);
}
int main()
{
cin>>s1>>s2;
l1=s1.length();
l2=s2.length();
s1=" "+s1;
s2=" "+s2;
for(int i=1;i<=l1;i++)
for(int j=1;j<=l2;j++)
{
if(s1[i]==s2[j]) f[i][j]=f[i-1][j-1]+1,re[i][j]=i-1,pre[i][j]=j-1;
else if(f[i-1][j]>f[i][j-1]) f[i][j]=f[i-1][j],re[i][j]=i-1,pre[i][j]=j;
else f[i][j]=f[i][j-1],re[i][j]=i,pre[i][j]=j-1;
}
cout<<f[l1][l2]<<endl;
out(l1,l2);
}