Sample Input
die einkommen der landwirte#
Sample Output
die einkommen der abgeordneten muessen dringend verbessert werden
/* 最长公共子序列+途径输出 Sample Input die einkommen der landwirte sind fuer die abgeordneten ein buch mit sieben siegeln um dem abzuhelfen muessen dringend alle subventionsgesetze verbessert werden # die steuern auf vermoegen und einkommen sollten nach meinung der abgeordneten nachdruecklich erhoben werden dazu muessen die kontrollbefugnisse der finanzbehoerden dringend verbessert werden # Sample Output die einkommen der abgeordneten muessen dringend verbessert werden 题意:输入两个字符串,每个字符串遇到 # 结束,判断两个字符串的最长公共子序列,输出最长公共串,题目要求最长公共串至少有一个。 本题的难点在于路径的记录,想了好久,有些细节问题还是没有注意,看了看大牛的博客,用两个数组标记上一步的位置,全部访问完后再往前遍历, 用栈存储或者用递归都可以,本题用的栈。 */ #include <iostream> #include <algorithm> #include <stdio.h> #include <string> #include <string.h> #include <stack> using namespace std; int dp[110][110]; int pos_a[110][110]; int pos_b[110][110]; string a[110],b[110]; int main() { int i,j; while(cin >> a[1]) { ///输入两个字符串 for(i = 2; ;i ++) { cin >> a[i]; if(a[i] == "#") { i --; break; } } for(j = 1; ;j ++) { cin >> b[j]; if(b[j] == "#") { j --; break; } } memset(dp,0,sizeof(dp)); memset(pos_a,0,sizeof(pos_a)); memset(pos_b,0,sizeof(pos_b)); int n = i ,m = j; for(i = 1; i <= n; i ++) for(j = 1; j <= m; j ++) { ///每种情况的上一步都记录下来 if(a[i] == b[j]) { dp[i][j] = dp[i-1][j-1] + 1; pos_a[i][j] = i-1; pos_b[i][j] = j-1; } else { if(dp[i-1][j] > dp[i][j-1]) { dp[i][j] = dp[i-1][j]; pos_a[i][j] = i-1; pos_b[i][j] = j; } else { dp[i][j] = dp[i][j-1]; pos_a[i][j] = i; pos_b[i][j] = j-1; } } } stack<string>s; while(n >= 1 & m >= 1) { if(a[n] == b[m])///如果相等的话,入栈 s.push(a[n]); ///注意这个赋值,不然到下面会产生错误 ///访问上一个位置 int t = n; n = pos_a[n][m]; m = pos_b[t][m]; } ///输出 while(s.size() > 1) { cout << s.top() << " "; s.pop(); } cout << s.top()<<endl; } return 0; }