Cod sursa(job #147482)

Utilizator webspiderDumitru Bogdan webspider Data 2 martie 2008 22:56:48
Problema NKPerm Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.05 kb
#include <stdio.h>
#include <iostream>
#include <map>

using namespace std;

const int maxP = 20*21*21*21*21*21 - 1; 
const int maxK = 6;
const int maxN = 21;

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

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

long long numara( int ultimu ) {
	long long Y;
	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 ]++;
			if ( i == ultimu ) Y += cate[i]*numara(i+1);
			else Y += (cate[i]+1)*numara(i+1);
			cate[ i+1 ]--;
			cate[ i ]++;
		}
	nSol[ calc_stare( ultimu ) ] = Y;
	return Y;
}
	

void opA() {
	rez = 1;
	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 ) {
				cate[ ap[j] ]--;
				ap[j]++;
				cate[ ap[j] ]++;
				rez += numara( ap[j] );
				cate[ ap[j] ]--;
				ap[j]--;
				cate[ ap[j] ]++;
			}
		last = aux;
		cate[ ap[aux] ]--;
		cate[ ++ap[aux] ]++;

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

void opB() {
	rez = 0;
	long long Y;
	int last;
	scanf("%d\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 ( rez + Y >= X ) {
				printf("%d ", j );
				last = j;
				break;
			}
			else {
				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;
}