Cod sursa(job #163777)

Utilizator bogdan2412Bogdan-Cristian Tataroiu bogdan2412 Data 23 martie 2008 10:20:18
Problema Sortare Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.11 kb
#include <stdio.h>
#include <string.h>

#define MAXN 5010
#define FOR(i, a, b) for (int (i) = (a); (i) <= (int)(b); ++(i))

int N, A[MAXN], B[MAXN], C[MAXN];
int bst[MAXN], p[MAXN];

inline int MAX( int a, int b )
{
	if (a > b)
		return a;
	return b;
}

int sol[MAXN], tmp[MAXN];

void rebuild( int l, int r )
{
	int len = r - l + 1;

	if (len == 0)
		return;
	if (len == 1)
	{
		sol[l] = 1;
		return;
	}

	int lenL = p[len] - 1;

	rebuild( l, l + lenL - 1 );
	rebuild( l + lenL, r - 1 );
	FOR(k, l + lenL, r)
		sol[k] += lenL + 1;

	int forcedL = -1, forcedR = -1;

	memset( tmp, 0, sizeof(tmp) );
	if (A[len] == B[len] && B[len] == C[len])					//toate egale
		tmp[ l + A[len] - 1 ] = p[len];
	else
		if (A[len] != B[len] && B[len] != C[len] && A[len] != C[len])		//toate diferite
		{
			tmp[ l + A[len] - 1 ] = p[len];

			forcedL = l + B[len] - 1;
			forcedR = l + C[len] - 1;
		}
		else									//2 egale
		{
			int eq = -1, dif = -1;

			if (A[len] == B[len])
				eq = A[len], dif = C[len];
			if (A[len] == C[len])
				eq = A[len], dif = B[len];
			if (B[len] == C[len])
				eq = B[len], dif = A[len];

			tmp[ l + eq - 1 ] = p[len];
			if (lenL)
				forcedL = l + dif - 1;
			else
				forcedR = l + dif - 1;
		}
	int poz = l;
	for (int k = l; k <= l + lenL - 1; k++)
	{
		if (k == l + lenL - 1 && poz < forcedL)
		{
			tmp[ forcedL ] = sol[k];
			break;
		}

		for (; tmp[poz] || poz == forcedR; poz++);

		tmp[poz] = sol[k]; poz++;
	}
	for (int k = l + lenL; k <= r - 1; k++)
	{
		for (; tmp[poz]; poz++);
		
		tmp[poz] = sol[k]; poz++;
	}

	FOR(k, l, r)
		sol[k] = tmp[k];
}

int main()
{
	freopen("sortare.in", "rt", stdin);
	freopen("sortare.out", "wt", stdout);

	scanf("%d", &N);
	FOR(i, 2, N)
		scanf("%d %d %d", A + i, B + i, C + i);

	bst[0] = bst[1] = 1;
	FOR(i, 2, N)
	{
		bst[i] = -1;
		FOR(j, 1, i)
		{
			if (A[i] != B[i] && B[i] != C[i] && A[i] != C[i] && (j == 1 || j == i))
				continue;

			int depth = MAX( bst[j - 1], bst[i - j] ) + 1;
			if (depth > bst[i])
			{
				bst[i] = depth;
				p[i] = j;
			}
		}
	}

	printf("%d\n", bst[N]);
	rebuild( 1, N );
	FOR(i, 1, N - 1)
		printf("%d ", sol[i]);
	printf("%d\n", sol[N]);

	return 0;
}