UVa 531 - Compromise

传送门

UVa 531 - Compromise

题意

给出两段英文单词,求它们的最长公共单词,并输出。

思路

看懂那个公共子序列的图就行,然后沿着路径走到头,递归输出。

公共子序列

代码

#include <cstdio>
#include <cstring>
using namespace std;
 
char a[110][40], b[110][40];
int dp[110][110], path[110][110];
int na = 0, nb = 0;
bool first = true;
 
void Initial()
{
    memset(dp, 0, sizeof(dp));
    memset(path, 0, sizeof(path));
    na = nb = 0;
    first = true;
}
 
void PrintAns(int i, int j)
{
    if (i == 0 || j == 0)
        return;
    if (path[i][j] == 1)
    {
        PrintAns(i - 1, j - 1);
        if (first)
            printf("%s", a[i - 1]), first = false;
        else
            printf(" %s", a[i - 1]);
    }
    else if (path[i][j] == 2)
        PrintAns(i, j - 1);
    else
        PrintAns(i - 1, j);
}
         
int main()
{
    //freopen("in.txt", "r", stdin);
    int i, j;
    while (~scanf("%s", a[na]))
    {
        if (a[na][0] == '#')
        {
            while (scanf("%s", b[nb]), b[nb][0] != '#')
                nb++;
            for (i = 1; i <= na; i++)
                for (j = 1; j <= nb; j++)
                {
                    if (strcmp(a[i - 1], b[j - 1]) == 0)
                    {
                        dp[i][j] = dp[i - 1][j - 1] + 1;
                        path[i][j] = 1;
                    }
                    else if (dp[i][j - 1] >= dp[i - 1][j])
                    {
                        dp[i][j] = dp[i][j - 1];
                        path[i][j] = 2;
                    }
                    else
                    {
                        dp[i][j] = dp[i - 1][j];
                        path[i][j] = 3;
                    }
                }
            //printf("%d\n", dp[na][nb]);
            PrintAns(na, nb);
            printf("\n");
            Initial();
            continue;
        }
        na++;
    }
    return 0;
}

Powered by Jekyll and Theme by solid