UVA 531 Compromise

大意:最长公共子串+路径输出。

思路:一开始我想用map爆过去,后来发现有重复的不好处理,只好老老实实地用LCS+路径输出来做咯,路径输出在王晓东那本算法书上有明确的讲解。

#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <cmath>
#include <map>
using namespace std;

char x[110][36], y[110][36];
int d[110][110];
int path[110][110];

int first;
int n, m;
int tot;

void init()
{
	n = 1;
	m = 0;
	first = 1;
	memset(d, 0, sizeof(d));
}

void LCS(int n, int m)
{
	int i, j;
	for(i = 1; i <= n; i++)
	{
		for(j = 1; j <= m; j++)
		{
			if(strcmp(x[i-1], y[j-1]) == 0)
			{
				d[i][j] = d[i-1][j-1]+1;
				path[i-1][j-1] = 1;
			}
			else if(d[i-1][j] >= d[i][j-1])
			{
				d[i][j] = d[i-1][j];
				path[i-1][j-1] = 2;
			}
			else
			{
				d[i][j] = d[i][j-1];
				path[i-1][j-1] = 3;
			}
		}
	}
}

void print_ans(int i, int j)
{
	if(i < 0 || j < 0) return ;
	if(path[i][j] == 1)
	{
		print_ans(i-1, j-1);
		if(first) {	printf("%s", x[i]); first = 0;}
		else printf(" %s", x[i]);
	}
	else if(path[i][j] == 2) print_ans(i-1, j);
	else print_ans(i, j-1);
}

void read_case()
{
	while(scanf("%s", x[n]) && strcmp(x[n], "#")) n++;
	while(scanf("%s", y[m]) && strcmp(y[m], "#")) m++;
}

void solve()
{
	init();
	read_case();
	LCS(n, m);
	print_ans(n-1, m-1);
	printf("\n");
}

int main()
{
	while(~scanf("%s", x[0]))
	{
		solve();
	}
	return 0;
}


你可能感兴趣的:(UVA 531 Compromise)