Cod sursa(job #109961)

Utilizator fireatmyselfBogdan-Alexandru Stoica fireatmyself Data 25 noiembrie 2007 12:59:53
Problema NKPerm Scor 10
Compilator c Status done
Runda preONI 2008, Runda 1, Clasele 11-12 Marime 4.97 kb
#include <stdio.h>
#define NMAX 111

int V[NMAX], X[NMAX], R[NMAX], N, K, M;
int Sol[1000][NMAX], T, Viz[NMAX];
long long F[NMAX], nsol;

void back(int nv)
{
        int i, j, ok, num;
        if (nv==M+1)
        {
                for (i = 2, ok = 1; i < nv && ok; i++)
                    if (X[ V[i] ]==X[ V[i-1] ]) ok = 0;
                if (ok)
                {
                   for (i = nsol-1; ok && i >= 0; i--)
                   {
                       for (j = num = 0; j < nv; j++)
                           if (X[ V[j] ]==Sol[i][j]) num++;
                       if (num==nv) ok = 0;
                       else ok = 1;
                   }
                   if (ok) {
                   for (j = 0; j < nv; j++) Sol[nsol][j] = X[ V[j] ];
                   nsol++; }
                }
                return;
        }

        for (i = 1; i <= M; i++)
        {
                for (j = ok = 1; ok && j < nv; j++)
                    if (V[j]==i) ok = 0;
                if (ok) {
                   V[nv] = i;
                   back(nv+1); }
        }
}

int main()
{
        int i, j, num = 0, n, cf, ok, k;
        char c;

        freopen("nkperm.in", "r", stdin);
        freopen("nkperm.out", "w", stdout);
        scanf("%d %d", &N, &K);
        n = N;
        for (i = 1; i <= N; i++)
            for (j = 1; j <= K; j++)
                X[++M] = i;
        if (M<10)
        {
                back(1);
                scanf("%d", &T);
                while (T--)
                {
                        scanf(" %c", &c);
                        if (c=='A')
                        {
                           for (i = 1; i <= M; i++) scanf("%d", R+i);
                           for (i = 0; i < nsol; i++)
                           {
                               for (j = num = 0; j <= M; j++)
                                   if (R[j]==Sol[i][j]) num++;
                               if (num>M)
                               {
                                        printf("%d\n", i+1);
                                        break;
                               }
                           }
                        }
                        else
                        {
                                scanf("%d", &i);
                                for (j = 1; j <= M; j++) printf("%d ", Sol[i-1][j]);
                                printf("\n");
                        }
                }
        }
        else
        if (K==1)
        {
                memset(Viz,0,sizeof(Viz));
                F[0] = 1;
                for (i = 1; i <= 20; i++) F[i] = F[i-1]*i;
                scanf("%d", &T);
                while (T--)
                {
                        scanf(" %c", &c);
                        if (c=='A')
                        {
                                nsol = 0;
                                N = n;
                                for (i = 1; i <= M; i++) scanf("%d", R+i);
                                for (i = 1; i <= M; i++)
                                {
                                        nsol += (R[i]-1)*F[--N];
                                        if (R[i]<(n-i+1))
                                        for (j = i+1; j <= M; j++)
                                            if (R[j]>1)
                                            {
                                               ok = 1;
                                               for (k = i+1; k < j; k++)
                                                   if ((R[j]-1)==R[k]) { ok = 0; break; }
                                               if (R[j]==2)
                                                  for (k = i+1; k <= M; k++)
                                                      if (R[k]==1) { ok = 0; break; }
                                               if (ok) R[j]--;
                                            }
                                }
                                printf("%lld\n", 1+nsol);
                        }
                        else
                        {
                                scanf("%d", &nsol);
                                N = n;
                                for (j = 0; j < M; j++)
                                {
                                        cf = 1;
                                        while (F[N-1]*cf<=nsol) cf++;
                                        nsol -= (cf-1)*F[N-1];
                                        N--;
                                        printf("%d ", j+cf);
                                        Viz[j+cf] = 1;
                                        if (nsol==0) break;
                                }
                                for (i = 1; i <= M; i++)
                                    if (!Viz[i]) printf("%d ", i);
                                printf("\n");
                        }
                }
        }
        
        return 0;
        
}