UVA 11421 - Arranging Cards

来源:互联网 发布:淘宝拍图摄影工作室 编辑:程序博客网 时间:2024/04/28 08:23

Problem E
Arranging Cards
Input:
Standard Input

Output: Standard Output

 

Given n (n <= 50) different cards, you're going to arrange them in a sequence so that adjacent cards always have different ranks.

 

Each card is represented by two characters: its rank (2~9,T for ten,J for Jack,Q for Queen,K for King,A for Ace) and suite (S for Spade,C for Club,H for Heart,D for Diamond). The whole sequence is represented by the concatenation of all the cards. For example, 6H7DJDKC is a valid sequence, but 6H7D7SKC is not, because there are two adjacent cards 7D and 7S with the same rank.

 

Given a positive integer k (1 ≤ k ≤ 1018), find the lexicographically k-th smallest sequence.

 

Input

The input contains at most 1000 test cases. Each case begins with two integers n and k in the first line. The second line contains n cards separated by a single space. The case with n = 0 indicates the end of the input and should not be processed.

 

Output

For each case, print the case number and the answer. If there is no such sequence, print "Not found" (without quotes). Insert a single space between each two adjacent cards to make it look better.

 

Sample Input

6 1

2S 3S 3C 4S 4C 4D

6 120

2S 3S 3C 4S 4C 4D

6 121

2S 3S 3C 4S 4C 4D

16 654321234567

2S 3S 4S 5S 2C 3C 4C 5C 2D 3D 4D 5D 2H 3H 4H 5H

0 0

 

Output for Sample Input

Case 1: 2S 4C 3C 4D 3S 4S

Case 2: 4S 3S 4D 3C 4C 2S

Case 3: Not found

Case 4: 5D 4S 2D 5H 3S 4H 5S 2H 3D 2C 5C 4D 2S 3C 4C 3H


Problemsetter: Rujia Liu

Special thanks: Dong Zhou

 


题意:有n张牌,各个牌是不一样的,即使他们有一样的rank和suit也是不一样的。 现在要将他们排成一行,并且相邻的牌的rank不一样。 求字典序是第k小的情况。


思路:算是这题的加强版.....http://www.lydsy.com/JudgeOnline/problem.php?id=1079


代码:

#include <iostream>#include <vector>#include <algorithm>#include <string.h>#include <cstring>#include <map>#include <set>#include <stdio.h>#include <cmath>#include <cassert>#include <math.h>#define rep(i,a,b) for(int i=(a);i<(b);++i)#define rrep(i,b,a) for(int i = (b); i >= (a); --i)#define clr(a,x) memset(a,(x),sizeof(a))#define LL unsigned long long#define eps 1e-9#define mp make_pairusing namespace std;const LL maxk = 1e18;struct State{    short pre;    short a[51];    bool operator < (const State & st) const    {        if (pre != st.pre) return pre < st.pre;        rep(i,0,51)        if (a[i] != st.a[i]) return a[i] < st.a[i];        return false;    }    bool operator == (const State & st) const    {        if (pre != st.pre) return false;        rep(i,0,51) if (a[i] != st.a[i]) return false;        return true;    }};const int maxn = 50+5;int n;long long K;map<State,LL> dp;int num[256],sum[maxn];pair<char,char> card[maxn];void input(){    char s[10];    rep(i,0,n) {        scanf("%s",s);        card[i] = mp(s[0],s[1]);    }    sort(card,card+n);}int ans[maxn];bool vis[maxn];LL add(LL a,LL b){    if (a >= maxk || b >= maxk        || a + b >= maxk) return maxk;    return a + b;}LL mul(LL a,LL b){    if (a > b) swap(a,b);    if (b >= maxk) return maxk;    if (a > maxk / b) return maxk;    return a * b;}LL dfs(State st){    map<State,LL>::iterator it;    it = dp.find(st);    if (it != dp.end()) return it->second;    LL & t = dp[st];    int n = 0,maxi = 0;    rep(i,0,51) {        n += st.a[i] * i;        if (st.a[i] > 0) maxi = i;    }    if (n == 0) return t = 1;    if (maxi + maxi - 1 > n) return t = 0;    int pre = st.pre;    rep(i,1,51) if (st.a[i]) {        --st.a[i];        if (i - 1 > 0) ++st.a[i-1];        st.pre = i;        t = add(t,dfs(st) * (st.a[i] + 1 - (pre == i+1)));        ++st.a[i];        if (i - 1 > 0) --st.a[i-1];        if (t >= maxk) break;    }    return t;}LL A[maxn];void solve(){    clr(num,0); clr(sum,0);    rep(i,0,n) {        int x = ++num[card[i].first];        ++sum[x]; --sum[x-1];    }    State start; clr(start.a,0);    rep(i,1,n+1) {        start.a[i] = sum[i];        start.pre = maxn*2;    }    clr(vis,0);    bool no_ans = false;    rep(i,0,n) {        int j = 0;        for(; j < n; ++j) if (!vis[j]) {            if (i > 0 && card[ans[i-1]].first == card[j].first) continue;            int x = --num[card[j].first];            vis[j] = true;            if (x > 0) ++start.a[x];            --start.a[x+1];            start.pre = x+1;            //++sum[x]; --sum[x+1];            LL t = dfs(start);            LL a = 1;            rep(k,2,n+1) {                rep(w,0,start.a[k]) {                    a = mul(a,A[k]);                    if (a >= K) break;                }                if (a >= K) break;            }            t = mul(t,a);            if (t >= K) break;            vis[j] = false;            K -= t;            if (x > 0) --start.a[x];            ++start.a[x+1];            ++num[card[j].first];        }        if (j >= n) {            no_ans = true;            break;        }        ans[i] = j;    }    if (no_ans || K != 1) puts("Not found");    else {        rep(i,0,n) {            char x = card[ans[i]].first;            char y = card[ans[i]].second;            printf("%c%c",x,y);            if (i != n-1) printf(" ");        }        puts("");    }}int main(){    #ifdef ACM        freopen("in.txt", "r", stdin);       // freopen("out.txt","w",stdout);    #endif // ACM    int cas = 0;    A[0] = 1;    rep(i,1,maxn) A[i] = mul(A[i-1],i);    while (scanf("%d",&n)==1) {        scanf("%lld",&K);        if (n == 0) break;        input();        ++cas;        printf("Case %d: ",cas);        solve();    }}


0 0
原创粉丝点击