(LCS)hdu 1503 Advanced Fruits

题目
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;
}

猜你喜欢

转载自blog.csdn.net/ymxyld/article/details/113763421