Cod sursa(job #1743381)

Utilizator fanache99Constantin-Buliga Stefan fanache99 Data 18 august 2016 02:49:32
Problema NKPerm Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.86 kb
#include<cstdio>
#include<map>
#include<cstring>
#define MAXK 10
#define MAXN 30
#define LIMIT (1LL<<55)
using namespace std;
map<int,long long> dp;
int n,k,t;
int power[MAXK],frequency[MAXN],howMany[MAXK];
int v[MAXN*MAXK];
int Hash(int last){
    int i;
    for(i=1;i<=k;i++)
        last=last+power[i]*howMany[i];
    return last;
}
long long Count(int last){
    int i,mask=Hash(last);
    long long answer=0;
    if(dp.find(mask)!=dp.end())
        return dp[mask];
    if(howMany[k]==n)
        return 1;
    for(i=0;i<k;i++)
        if(howMany[i]!=0){
            howMany[i]--;
            howMany[i+1]++;
            if(last==i)
                answer=answer+howMany[i]*Count(i+1);
            else
                answer=answer+(howMany[i]+1)*Count(i+1);
            howMany[i+1]--;
            howMany[i]++;
            if(answer>=LIMIT){
                dp[mask]=answer;
                return LIMIT;
            }
        }
    dp[mask]=answer;
    return answer;
}
void SolveA(){
    int i,j;
    long long answer=1;
    char enter;
    memset(howMany,0,sizeof(howMany));
    memset(frequency,0,sizeof(frequency));
    for(i=1;i<=n*k;i++)
        scanf("%d%c",&v[i],&enter);
    howMany[0]=n;
    for(i=1;i<=n*k;i++){
        for(j=1;j<v[i];j++)
            if(j!=v[i-1]&&frequency[j]<k){
                howMany[frequency[j]]--;
                frequency[j]++;
                howMany[frequency[j]]++;
                answer+=Count(frequency[j]);
                howMany[frequency[j]]--;
                frequency[j]--;
                howMany[frequency[j]]++;
            }
        howMany[frequency[v[i]]]--;
        frequency[v[i]]++;
        howMany[frequency[v[i]]]++;
    }
    printf("%lld\n",answer);
}
void SolveB(){
    int i,j,last=0;
    long long value,temp;
    memset(howMany,0,sizeof(howMany));
    memset(frequency,0,sizeof(frequency));
    scanf("%lld\n",&value);
    howMany[0]=n;
    for(i=1;i<=n*k;i++){
        for(j=1;j<=n;j++)
            if(j!=last&&frequency[j]<k){
                howMany[frequency[j]]--;
                frequency[j]++;
                howMany[frequency[j]]++;
                temp=Count(frequency[j]);
                if(temp>=value)
                    break;
                value-=temp;
                howMany[frequency[j]]--;
                frequency[j]--;
                howMany[frequency[j]]++;
            }
        last=j;
        printf("%d ",j);
    }
    printf("\n");
}
int main(){
    freopen("nkperm.in","r",stdin);
    freopen("nkperm.out","w",stdout);
    int i;
    char type;
    scanf("%d%d%d\n",&n,&k,&t);
    power[1]=n+1;
    for(i=2;i<=k;i++)
        power[i]=power[i-1]*(n+1);
    for(i=1;i<=t;i++){
        scanf("%c",&type);
        if(type=='A')
            SolveA();
        else
            SolveB();
    }
    return 0;
}