Cod sursa(job #2437494)

Utilizator Ruxandra985Nanu Ruxandra Laura Ruxandra985 Data 9 iulie 2019 17:30:36
Problema NKPerm Scor 20
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.79 kb
#include <cstdio>
#include <map>
#define BASE 21

using namespace std;
int n,k;
int apar[30],nr[6];
long long INF=36028797018963968 , sol = 0;
map <int , long long> mp;
int b[6],v[110],w[110];

void back (int fqlast , int cod){
    int i;
    long long aux;
    /// stii deja ca ai un prefix valid
    int newc = cod + b[k] * fqlast;
    if (mp[ newc ] != 0){
        sol+= mp[ newc ];
        return;
    }
    if (nr[k] == n){
        mp[newc] = 1;
        sol++;
        return;
    }
    for (i=0;i<k;i++){
        if (nr[i]){
            nr[i]--;
            nr[i+1]++;
            cod = cod - b[i] + b[i+1];
            aux = sol;
            if (i == fqlast){
                sol = 0;
                back(i+1,cod);
                sol = (long long)nr[i] * sol;
            }
            else {
                sol = 0;
                back(i+1,cod);
                sol = (long long)(nr[i]+1) * sol;
            }
            sol += aux;
            if ( sol > INF){

                mp[ newc ] = INF;
                sol = INF;
                return;

            }

            nr[i]++;
            nr[i+1]--;
            cod = cod + b[i] - b[i+1];
        }
    }
    mp[ newc ] = sol;
    return;
}
long long solve_a (){
    int i,j;
    int cod = 0 , ca = 0;
    sol = 0;
    for (i=1;i<=n;i++)
        apar[i] = 0;

    nr[0] = n;
    for (i=1;i<=k;i++)
        nr[i] = 0;

    for (i=1;i<=n*k;i++){
        for (j=1;j<v[i];j++){
            if (j!=w[i-1] && apar[j] + 1 <=k){
                w[i] = j;
                ca = cod;
                cod = cod - b[apar[j]] + b[apar[j] + 1];
                apar[j]++;
                nr[apar[j]-1] --;
                nr [apar[j]]++;
                back(apar[j], cod);
                cod = ca;
                nr[apar[j]-1] ++;
                nr [apar[j]]--;
                apar[j]--;
            }
        }
        w[i] = v[i];
        cod = cod - b[apar[j]] + b[apar[j] + 1];
        apar[j]++;
        nr[apar[j]-1] --;
        nr[apar[j]]++;
    }
    return sol;
}
inline void solve_b (long long x){
    int i,j;
    int cod = 0 , ca;

    for (i=1;i<=n;i++)
        apar[i] = 0;

    nr[0] = n;
    for (i=1;i<=k;i++)
        nr[i] = 0;

    for (i=1;i<=n*k;i++){
        for (j=1;j<=n;j++){
            if (j!=w[i-1] && apar[j] + 1 <=k){
                w[i] = j;
                ca = cod;
                cod = cod - b[apar[j]] + b[apar[j] + 1];
                apar[j]++;
                nr [apar[j]-1] --;
                nr [apar[j]]++;
                sol = 0;
                back(apar[j] , cod);
                if (x - sol <= 0){
                    w[i] = j;
                    break;
                }
                else{
                    x-=sol;
                    cod = ca;
                    nr[apar[j]-1] ++;
                    nr [apar[j]]--;
                    apar[j]--;
                }
            }
        }
        v[i] = w[i];
        //printf ("%d ",v[i]);
    }
}
int main()
{
    FILE *fin = fopen ("nkperm.in","r");
    FILE *fout = fopen ("nkperm.out","w");
    int i,t;
    long long x;
    char c;
    fscanf (fin,"%d%d",&n,&k);
    /// precalculari

    b[0] = 1;
    for (i=1;i<=k;i++)
        b[i] = b[i-1] * BASE;

    fscanf (fin,"%d\n",&t);
    for (;t;t--){
        c=fgetc (fin);
        if (c=='A'){
            for (i=1;i<=n*k;i++){
                fscanf (fin,"%d",&v[i]);
            }
            fgetc (fin);
            fprintf (fout,"%lld\n",solve_a() + 1);
        }
        else {
            fscanf (fin,"%lld\n",&x);
            solve_b(x);
            for (i=1;i<=n*k;i++)
                fprintf (fout,"%d ",v[i]);
            fprintf (fout,"\n");
        }
    }
    return 0;
}