题目
hdu1503
题意:
两个字符串融合成一个字符串,使得这个字符串的子字符串(可以不连续)是给出的这两个字符串,并且这个融合的字符串的长度最小(可能有多个答案,输出其中一个即可)。
as:apple + pear = applear,cranberry + boysenberry = boysecranberry(或craboysenberry)
思路:
先LCS,再根据LCS推出两个字符串相同字符的坐标,再根据这些坐标把两个字符串拆开再连接即可。
代码
#include <bits/stdc++.h>
#define DEBUG freopen("_in.txt", "r", stdin); freopen("_out1.txt", "w", stdout);
using namespace std;
const int MAXN = 1e2 + 10;
char a[MAXN], b[MAXN], ans[MAXN<<1];
int patha[MAXN], pathb[MAXN];
int dp[MAXN][MAXN];
int main(){
while (~scanf(" %s %s", a, b)){
int lena = strlen(a);
int lenb = strlen(b);
for (int i = 0; i < lenb; i++)
dp[0][i] = 0;
for (int i = 0; i < lena; i++)
dp[i][0] = 0;
for (int i = 1; i <= lena; i++)
for (int j = 1; j <= lenb; j++)
if (a[i-1] == b[j-1])
dp[i][j] = dp[i-1][j-1] + 1;
else
dp[i][j] = max(dp[i-1][j], dp[i][j-1]);
int vi = 0, i = lena, j = lenb;
while (vi < dp[lena][lenb]){
if (a[i-1] == b[j-1]){
patha[vi] = --i;
pathb[vi++] = --j;
}
else if (dp[i-1][j] > dp[i][j-1])
i--;
else
j--;
}
int ti = vi - 1;
int ansi = 0;
for (int i = 0; i < patha[ti]; i++)
ans[ansi++] = a[i];
for (int i = 0; i < pathb[ti]; i++)
ans[ansi++] = b[i];
ans[ansi++] = a[patha[ti--]];
while (ti >= 0){
for (int i = patha[ti+1] + 1; i < patha[ti]; i++)
ans[ansi++] = a[i];
for (int i = pathb[ti+1] + 1; i < pathb[ti]; i++)
ans[ansi++] = b[i];
ans[ansi++] = a[patha[ti--]];
}
for (int i = patha[0] + 1; i < lena; i++)
ans[ansi++] = a[i];
for (int i = pathb[0] + 1; i < lenb; i++)
ans[ansi++] = b[i];
ans[ansi] = '\0';
printf("%s\n", ans);
}
return 0;
}