Cod sursa(job #148119)

Utilizator webspiderDumitru Bogdan webspider Data 3 martie 2008 21:56:44
Problema NKPerm Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.22 kb
#include <stdio.h>
#include <iostream>
#include <map>

using namespace std;

const int maxK = 6;
const int maxN = 21;

map< int, long long > nSol;
int N, K, T;
int cate[ maxK ];
int ap[ maxN ];

int calc_stare( int ultimu ) {
	int cod = 0;
	for ( int i = 1; i <= K; i++ ) cod += cod * ( N+1 ) + cate[ i ];
	cod = cod * ( N+1 ) + ultimu;
	return cod;
}

long long numara( int ultimu ) {
	long long Y;
	long long aX;
	int ST = calc_stare( ultimu );
	if ( nSol.find( ST ) != nSol.end() ) return nSol[ ST ];
	if ( cate[ K ] == N ) return 1;
	Y = 0;
	for ( int i = 0; i < K; i++ )
		if ( cate[ i ] != 0 ) {
			cate[ i ]--;
			cate[ i+1 ]++;
			aX = numara( i+1 );
			if ( i == ultimu ) Y = ( long long ) Y + cate[i]*aX;
			else Y = ( long long ) Y + (cate[i]+1)*aX;
			cate[ i+1 ]--;
			cate[ i ]++;
			if ( Y >= ( 1LL<<55 ) ) { Y = ( 1LL << 55 ); break; }
		}
	nSol[ ST ] = Y;
	return Y;
}
	

void opA() {
	long long rez = 1;
	long long X = 0;
	int aux;
	int last = 0;
	memset( ap, 0, sizeof( ap ) );
	memset( cate, 0, sizeof( cate ) );
	cate[0] = N;
	for ( int i = 1; i <= N*K; i++ ) {
		scanf("%d\n", &aux);
		for ( int j = 1; j < aux; j++ ) 
			if ( j != last && ap[j] < K ) {
				cate[ ap[j] ]--;
				ap[j]++;
				cate[ ap[j] ]++;
				rez = ( long long ) rez + numara( ap[j] );
				cate[ ap[j] ]--;
				ap[j]--;
				cate[ ap[j] ]++;
			}
		last = aux;
		cate[ ap[aux] ]--;
		cate[ ++ap[aux] ]++;

	}
	printf("%lld\n", rez );
}

void opB() {
	long long rez = 0;
	long long Y = 0;
	long long X = 0;
	int last = 0;
	scanf("%lld\n", &X );
	memset( ap, 0, sizeof( ap ) );
	memset( cate, 0, sizeof( cate ) );
	cate[ 0 ] = N;
		
	for ( int i = 1; i <= N*K; i++ ) {
		for ( int j = 1; j <= N; j++ ) 
		if ( j != last && ap[ j ] < K ) {
			cate[ ap[j] ]--;
			ap[j]++;
			cate[ ap[j] ]++;
			Y =  numara( ap[j] );
			if ( ( long long ) rez + Y >= X ) {
				printf("%d ", j );
				last = j;
				break;
			}
			else {
				rez = ( long long ) rez + Y;
				cate[ ap[j] ]--;
				ap[j]--;
				cate[ ap[j] ]++;
			}
		}
	}
	printf("\n");
}

int main() 
{
	char cmd;
	freopen("nkperm.in","r",stdin);
	freopen("nkperm.out","w",stdout);

	scanf("%d %d %d\n", &N, &K, &T );

	for( ; T; --T ) {
		scanf("%c ", &cmd );
		if ( cmd == 'A' ) opA();
		if ( cmd == 'B' ) opB();
	}



	return 0;
}