Cod sursa(job #134533)

Utilizator MariusMarius Stroe Marius Data 11 februarie 2008 20:46:17
Problema Seif Scor 70
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.03 kb
#include <fstream>
#include <iostream>

#include <string>
#include <vector>
#include <algorithm>

using namespace std;

const char iname[] = "seif.in";
const char oname[] = "seif.out";

#define MAXN  1005

int L[MAXN][MAXN];

int first1[MAXN][26], first2[MAXN][26];


int work(char A[], char B[])
{
	int n = (int)strlen(A);
	int m = (int)strlen(B);

	for (int i = 0; i < n; ++ i)
		L[i][m] = 0;
	for (int j = 0; j < n; ++ j)
		L[n][j] = 0;
	L[n][m] = 0;
	for (int i = n - 1; i >= 0; -- i)
		for (int j = m- 1; j >= 0; -- j)
			if (A[i] == B[j])
				L[i][j] = L[i + 1][j + 1] + 1;
			else
				L[i][j] = max(L[i][j + 1], L[i + 1][j]);

	return L[0][0];
}

void workfirst(char A[], int first[][26])
{
	int n = (int)strlen(A);

	for (int j = 0; j < 26; ++ j)
		first[n][j] = n;
	for (int i = n - 1; i >= 0; -- i)
		for (int j = 0; j < 26; ++ j)
			first[i][j] = (A[i] == 'A' + j) ? i : first[i + 1][j];
}

void worksubstr(int length, char ret[])
{
	int i, j, ret_size = 0;
	bool equal = true, smallerlexi = false;

	i = j = 0;
	ret[length] = 0;
    for (; length > 0; -- length)
	{
		for (int litera = 25; litera >= 0; -- litera)
			if (L[ first1[i][litera] ][ first2[j][litera] ] >= length)
			{
				i = first1[i][litera] + 1;
				j = first2[j][litera] + 1;
				if (equal)
				{
					if (ret[ret_size] != litera + 'A')
						equal = false;
					if (!equal) 
						if (ret[ret_size] < litera + 'A')
							smallerlexi = true;
				}
				if (smallerlexi)
					ret[ret_size] = litera + 'A';
				ret_size ++;
				break ;
			}
	}
}

int main(void)
{
	ifstream fin(iname);
	ofstream fout(oname);
	
	char A[MAXN], B[MAXN], ret[MAXN];
	int css;
	int K;

	for (fin >> css; css > 0; -- css)
	{
		fin >> K;
		fin >> A >> B;
		int maxlensubstr = work(A, B);
		workfirst(A, first1);
		workfirst(B, first2);
		ret[0] = 0;
		for (int lensubstr = K; lensubstr <= maxlensubstr; ++ lensubstr)
			worksubstr(lensubstr, ret);
		fout << ret << '\n';
	}

	fin.close();
	fout.close();
	return 0;
}