1 条题解

  • 1
    @ 2025-4-5 22:13:12

    题意

    首先确定数字串的长度LenLen:从大到小枚举LenLen,每个LenLen下有15P(15,Len1)15*P(15, Len-1)个数字串。每次用这个个数扣除输入的序数CountCount,直到序数CountCount将扣为负数时停止,就确定了长度LenLen。然后从高位到低位,从大到小确定每位数字:设当前确定的数字为第ii位,则第ii位的任何一个取值,都有P(16(Leni+1),i1)P(16 - (Len - i + 1), i - 1)个数字串将已确定的第11ii位作为前缀。每次用这个个数扣除输入的序数CountCount,直到序数CountCount将扣为负数时停止,就确定了当前位的数字。 注意不能有前导00

    标程

    #include <iostream>
    
    char num[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
    int ans[10];
    
    int Axy(int x, int y) {
        int res = 1;
        if (y == 0)
            return 1;
        while (y--) {
            res *= x;
            x--;
        }
        return res;
    }
    
    void solve(int count) {
        bool vis[16] = {0}, head = false;
        int uselen = 0, countv;
        for (int i = 1; i <= 8; i++) {
            int cnt = 15;
            while (cnt) {
                if (!vis[cnt]) {
                    if ((countv = Axy(16 - 1 - uselen, 8 - i)) < count) {
                        count -= countv;
                    }
                    else {
                        vis[cnt] = true;
                        break;
                    }
                }
                cnt--;
            }
            ans[i] = num[cnt];
            if (head || ans[i] != '0')
                uselen++;
            if (ans[i] != '0')
                head = true;
        }
    }
    
    int main() {
        int cnt;
        while (std::cin >> cnt) {
            bool head = false;
            solve(cnt);
            for (int i = 1; i <= 8; i++) {
                if (head || ans[i] != '0') {     //去除前导0
                    std::cout << (char)ans[i];
                    head = true;
                }
            }
            if (!head)     // 若全为0 ,则输出0
                std::cout << 0;
            std::cout << std::endl;
        }
        return 0;
    }
    
    
    • 1

    信息

    ID
    716
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    2
    已通过
    1
    上传者