【基础】字典序第k大的排列

ll fac[18];

    int n, k, c;
    int last[18];

    void show() {
        printf("k=%d\n", k);
        for(int i = 1; i <= c; ++i)
            printf("%d%c", last[i], " \n"[i == c]);
    }

    void Solve() {
        ll pro = 1;
        bool ok = 0;
        fac[0] = 1;
        for(int i = 1; i <= 15; ++i)
            fac[i] = fac[i - 1] * i;
        for(int i = 1; i <= n; ++i) {
            pro *= i;
            if(pro >= k) {
                ok = 1;
                break;
            }
        }
        if(!ok) {
            puts("-1");
            return;
        }
//        for(int i = 0; i <= 15; ++i)
//            printf("fac[%d]=%lld\n", i, fac[i]);
        c = min(n, 15);
        for(int i = 1; i <= c; ++i)
            last[i] = n + 1 - i;
        sort(last + 1, last + 1 + c);
        --k;
        //show();
        for(int i = 1; k > 0 && i <= c; ++i) {
            //printf("len=%d fac=%lld\n", c - i, fac[c - i]);
            if(k < fac[c - i])
                continue;
            assert(k >= fac[c - i]);
            int kk = k / fac[c - i];
            swap(last[i], last[i + kk]);
            k %= fac[c - i];
            sort(last + i + 1, last + 1 + c);
            //show();
        }
        show();
        return;
    }
posted @ 2020-12-29 14:04  purinliang  阅读(241)  评论(0编辑  收藏  举报