题目:点击打开链接
题意:给你两个单词,找出它们的最长公共子序列,输出一个含有最长公共子序列的最短单词。
解法:lcs求最长公共子序列,dp[i][j]表示在s1的i位置,s2的j位置的最长公共子序列的长度;定义ans结构体倒序存最长公共子序列的字母,i存该字母在s1的位置,j存该字母在s2的位置;输出时分清情况一个字母一个字母的输出。
代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
#include <iostream>
#include <cstring>
using namespace std;
struct sa
{
int i,j;
char ch;
}ans[205];
int len1,len2,dp[105][105];
char s1[105],s2[105];
void lcs()
{
for(int i=1;i<=len1;i++)
for(int j=1;j<=len2;j++)
{
if(s1[i]==s2[j]) dp[i][j]=dp[i-1][j-1]+1;
else dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
}
}
int main()
{
int len,i,j;
while(cin>>s1+1>>s2+1)
{
len1=strlen(s1+1);
len2=strlen(s2+1);
memset(dp,0,sizeof(dp));
lcs();
if(dp[len1][len2]==0) cout<<s1+1<<s2+1<<endl;
else
{
len=0;
while(len1!=0&&len2!=0)
{
if(dp[len1][len2]==dp[len1-1][len2-1]+1&&s1[len1]==s2[len2])
{
ans[len].i=len1;
ans[len].j=len2;
ans[len++].ch=s1[len1];
len1--;
len2--;
}
else if(dp[len1-1][len2]>dp[len1][len2-1]) len1--;
else len2--;
}
}
i=j=1;
for(int k=len-1;k>=0;k--)
{
while(i!=ans[k].i)
{
cout<<s1[i];
i++;
}
while(j!=ans[k].j)
{
cout<<s2[j];
j++;
}
cout<<ans[k].ch;
i++;j++;
}
cout<<s1+1+ans[0].i<<s2+1+ans[0].j<<endl;
}
return 0;
}