IT民工
加油!

求文本的最长公共子序列,序列中每个元素都是一个字符串,学习了记录路径和递归输出的方法。

 

/*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;
}

 

 

 

posted on 2012-04-11 11:24  找回失去的  阅读(232)  评论(0编辑  收藏  举报