输出最长公共子序列
试题描述
|
还是公共子序列,如果不知道什么叫公共子序列,请先阅读第0071题。本题给定两个字符串 str1 和 str2 ,请编写程序求出这两个字符串最长的公共子串。如果最大长度的公共子串有多个,输出字典序最小的那一个。 |
输入
|
两行,每行一个只含英文字母的字符串
|
输出
|
一个字符串
|
输入示例
|
ABCDDDBAMN BCDABM
|
输出示例
|
BCDAM
|
其他说明
|
输入的字符串长度均不会超过1000。
|
#include<cstdio> #include<cctype> #include<algorithm> #include<cstring> #define maxn 1005 using namespace std; inline int read() { int x=0,f=1;char c=getchar(); for(;!isdigit(c);c=getchar()) if(c=='-')f=-1; for(;isdigit(c);c=getchar()) x=x*10+c-'0'; return x*f; } int lasta[maxn][27],lastb[maxn][27]; int f[maxn][maxn],ans[maxn],cnt; char a[maxn],b[maxn]; bool flag; void dfs(int res,int n,int m) { if(flag) return; if(res==0) { flag=1; for(int i=0;i<cnt;i++) printf("%c",ans[i]+'A'); printf("\n"); return; } for(int i=0;i<26;i++) { int posa=lasta[n][i],posb=lastb[m][i]; if(f[posa+1][posb+1]==res) { ans[cnt++]=i; dfs(res-1,posa-1,posb-1); cnt--; } } } int main() { scanf("%s%s",a,b); int n=strlen(a),m=strlen(b); for(int i=0;i<n/2;i++)swap(a[i],a[n-i-1]); for(int i=0;i<m/2;i++)swap(b[i],b[m-i-1]); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) if(a[i-1]==b[j-1]) f[i][j]=f[i-1][j-1]+1; else f[i][j]=max(f[i-1][j],f[i][j-1]); memset(lasta,-1,sizeof(lasta)); memset(lastb,-1,sizeof(lastb)); for(int i=0;i<n;i++) { for(int j=i;j>=0;j--) if(lasta[i][a[j]-'A']==-1) lasta[i][a[j]-'A']=j; } for(int i=0;i<m;i++) { for(int j=i;j>=0;j--) if(lastb[i][b[j]-'A']==-1) lastb[i][b[j]-'A']=j; } dfs(f[n][m],n-1,m-1); return 0; }