求文本的最长公共子序列,序列中每个元素都是一个字符串,学习了记录路径和递归输出的方法。
/*Accepted 224K 0MS C++ 1186B 2012-04-11 11:19:14 */ #include<cstdio> #include<cstring> #include<cstdlib> #define MAXN 105 #define MAXM 31 int f[MAXN][MAXN]; char a[MAXN][MAXM], b[MAXN][MAXM]; int mark[MAXN][MAXN]; int na, nb, cnt; void output( int i, int j) { if( i == 0 || j == 0) return; if( mark[i][j] == 0) { output( i - 1, j - 1); printf( "%s", a[i]); cnt ++; if( cnt > 0 && cnt != f[na - 1][nb - 1]) printf( " "); else printf( "\n"); } if( mark[i][j] == 1) output( i - 1, j); if( mark[i][j] == -1) output( i, j - 1); } void dp() { for( int i = 1; i <= na; i ++) for( int j = 1; j <= nb; j ++) { if( strcmp( a[i], b[j]) == 0) { mark[i][j] = 0; f[i][j] = f[i - 1][j - 1] + 1; } else { if( f[i - 1][j] > f[i][j - 1]) { mark[i][j] = 1; f[i][j] = f[i - 1][j]; } else { mark[i][j] = -1; f[i][j] = f[i][j - 1]; } } } } int main() { while( scanf( "%s", a[1]) != EOF) { if( a[1][0] != '#') for( na = 2; scanf( "%s", a[na]) && a[na][0] != '#'; na ++); for( nb = 1; scanf( "%s", b[nb]) && b[nb][0] != '#'; nb ++); dp(); cnt = 0; output( na - 1, nb - 1); } return 0; }