1. 程式人生 > >HDU 1503【LCS】(字符串合並輸出)

HDU 1503【LCS】(字符串合並輸出)

out oca ref problem else HP AC spa col

題目鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=1503

題目大意:

給兩個字符串,組成一個長度盡可能小的字符串,它包含上述兩個字符串,且原字符串中的字符在該串中的相對位置不變。

Sample Input apple peach ananas banana pear peach Sample Output appleach bananas pearch 解題思路:
要結合樣例來理解題意,本題主要難在如何輸出題目要求字符串,這就需要我們仔細研究樣例,去發掘它是如何輸出的,具體操作見代碼。
#include <iostream>
#include 
<string> #include <cstdio> using namespace std; int dp[110][110]; int vis[110][110]; //標記路徑 int loca[110], locb[110]; //記錄下最長公共子序列在這兩個字符串中的位置 int lena, lenb; //a,b序列的長度 int len; //記錄下最長公共子序列長度 string stra, strb; void locallcs(int i, int j) //標記好最長公共子序列的每一個字符分別在a,b字符中的位置 { len
= 0; while (i>0&&j>0) { if (vis[i][j] == 1) { loca[len] = i-1; // 此時loca,locb數組記錄的是最長公共子序列分別在啊a,b字符串中的位置 locb[len] = j-1; //不過要註意此時記錄的是逆序的,這個仔細看它存入的順序就能明白 len++; i--, j--; } else if (vis[i][j] == 2
)j--; else i--; } } void output() //輸出答案,至於為什麽是這樣輸出,自己仔細研究題目的輸出樣例就能發現 { int inverse = len - 1; int cur1 = 0,cur2=0; while (inverse >= 0) { for (int i = cur1; i<loca[inverse]; i++) //輸出a中兩個相鄰的公共子序列字符之間的字符 printf("%c", stra[i]); for (int j = cur2; j < locb[inverse]; j++) printf("%c", strb[j]); printf("%c", stra[loca[inverse]]); //輸出那個公共字符 cur1 = loca[inverse]+1, cur2=locb[inverse]+1; inverse--; } for (int i = loca[0]+1; i < lena; i++)printf("%c", stra[i]); //輸出最後一個公共子序列字符之後的字符 for (int j = locb[0]+1; j < lenb; j++)printf("%c", strb[j]); cout << endl; } int main() { while (cin >> stra >> strb) { lena = stra.length(); lenb = strb.length(); for (int i = 0; i <= lena; i++) { for (int j = 0; j <= lenb; j++) { if (!i || !j) { dp[i][j] = 0; continue; } if (stra[i - 1] == strb[j - 1]) { dp[i][j] = dp[i - 1][j - 1] + 1; vis[i][j] = 1; //標記輸出路徑 } else if (dp[i - 1][j] < dp[i][j - 1]) //dp數組在本題起控制標記路徑方向的作用 { dp[i][j] = dp[i][j - 1]; vis[i][j] = 2; } else { dp[i][j] = dp[i - 1][j]; vis[i][j] = 3; } } } locallcs(lena, lenb); output(); } return 0; }

2018-05-19

HDU 1503【LCS】(字符串合並輸出)