Cod sursa(job #1864838)

Utilizator alex_HarryBabalau Alexandru alex_Harry Data 1 februarie 2017 00:42:17
Problema NKPerm Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.39 kb
#include <fstream>
#include <map>
using namespace std;
ifstream f("nkperm.in");
ofstream g("nkperm.out");
int N, K, T;
const long long limit = (1LL << 55);
map <int, long long> M;
int Array[105];
int Cnt[7], X[25];
int V[7];
long long Count(int v[], int last)
{
    long long res = 0;
    int x = 0;
    for(int i = 0; i <= K; i++)
        x = x * (N + 1) + v[i];
    x = x * (N + 1) + last;
    if(M.find(x) != M.end())
        return M[x];
    if(v[K] == N)
    {
        M[x] = 1;
        return 1;
    }

    for(int i = 0; i < K; i++)
        if(v[i] > 0)
        {
            v[i]--;
            v[i + 1]++;
            long long val = Count(v, i + 1);
            if(i == last)
            {
                res += val * v[i];
            }
            else
                res += (val) * (v[i] + 1);
            v[i]++;
            v[i + 1]--;
            if(res >= limit)
            {
                res = limit;
                break;
            }
        }
    M[x] = res;
    return res;
}

void SolveA()
{
    int poz = 1, i = 1;
    long long sum = 0;
    Cnt[0] = N;
    for(int i = 1; i <= K; i++)
        Cnt[i] = 0;
    for(int i = 1; i <= N; i++)
        X[i] = 0;
    while(poz <= N * K)
    {
        for(int j = 1; j < Array[poz]; j++)
        {
            if(j == Array[poz - 1] || X[j] == K)
                continue;
            int last = X[j] + 1;
            Cnt[X[j]]--;
            X[j]++;
            Cnt[X[j]]++;
            /*int x = 0;
            for(int i = 0; i <= K; i++)
                x = x * (N + 1) + Cnt[i];
            x = x * (N + 1) + last;*/
            sum += Count(Cnt, last);
            Cnt[X[j]]--;
            X[j]--;
            Cnt[X[j]]++;
        }
        Cnt[X[Array[poz]]]--;
        X[Array[poz]]++;
        Cnt[X[Array[poz]]]++;
        ++poz;
    }
    g << sum + 1 << "\n";
}

void SolveB(long long a)
{
    int poz = 1, i = 1;
    long long sum = a;
    Cnt[0] = N;
    for(int i = 1; i <= K; i++)
        Cnt[i] = 0;
    for(int i = 1; i <= N; i++)
        X[i] = 0;
    while(poz <= N * K)
    {
        int nb;
        for(int j = 1; j <= N; j++)
        {
            if(j == Array[poz - 1] || X[j] == K)
                continue;
            int last = X[j] + 1;
            Cnt[X[j]]--;
            X[j]++;
            Cnt[X[j]]++;
            /*int x = 0;
            for(int i = 0; i <= K; i++)
                x = x * (N + 1) + Cnt[i];
            x = x * (N + 1) + last;*/
            if(sum <= Count(Cnt, last))
            {
                nb = j;
                Cnt[X[j]]--;
            X[j]--;
            Cnt[X[j]]++;
                break;
            }
            sum -= Count(Cnt, last);
            Cnt[X[j]]--;
            X[j]--;
            Cnt[X[j]]++;

        }
        Cnt[X[nb]]--;
        X[nb]++;
        Cnt[X[nb]]++;
        Array[poz] = nb;
        g << nb << " ";
        ++poz;
    }
    g << "\n";
}
int main()
{
    f >> N >> K >> T;
    V[0] = N;
    //Count(V, 0);
    for(int i = 1; i <= T; i++)
    {
        char type;
        f >> type;
        if(type == 'A')
        {
            for(int j = 1; j <= N * K; j++)
                f >> Array[j];
            SolveA();
        }
        else
        {
            long long X;
            f >> X;
            SolveB(X);
        }
    }
    return 0;
}