• POJ1715 Hexadecimal Numbers 组合数学


    这题写的真心有点纠结。首先确定需要多少位来容纳这个数,然后找到第一个要更新的位置,再逐位更新。

    代码如下:

    #include <cstdlib>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    using namespace std;
    
    typedef long long int Int64;
    
    bool hash[20];
    
    int digit[10], Most;
    
    Int64 s[10], f[20], N;
    
    void pre()
    {
        f[0] = s[0] = 1;
        for (int i = 1; i <= 16; ++i) {
            f[i] = f[i-1] * i;
        }
        for (int i = 1; i <= 8; ++i) {
            s[i] = f[16-Most+i] / f[16-Most];
        }
        s[Most] -= s[Most-1];
    }
    
    void update(int pos)
    {
        for (int i = 15; i >= 0; --i) {
            if (!hash[i]) {
                digit[pos] = i;    
                hash[digit[pos]] = true;
                return;
            }
        }
    }
    
    void dfs(int pos, Int64 k, int start)  
    // 需要开始调整的位置以及需要调整的指数
    {
        int deep = (int)floor(1.0 * k / s[pos-1]), cnt = 0, left;
        if (deep) {
            hash[digit[pos]] = false;
            for (int i = start; i >= 0; --i) {
                if (!hash[i]) {
                    ++cnt;
                }
                if (cnt == deep) {
                    digit[pos] = i;
                    hash[digit[pos]] = true;
                    break;
                }
            } // 这一位我们就确定了下来
        }
        left = k-deep*s[pos-1];
        if (pos-1 > 0) {
            update(pos-1);
            dfs(pos-1, left, digit[pos-1]-1);
        }
    }
    
    void init()
    {
        pre();
        memset(digit, 0, sizeof (digit));
        memset(hash, 0, sizeof (hash));
        for (int i = 16 - Most, j = 1; i <= 15; ++i, ++j) {
            hash[i] = true;  // 声明出这些数是已占用的 
            digit[j] = i;
        }
    }
    
    int main()
    {
        while (scanf("%I64d", &N) == 1) {
            pre();
            N -= 1;
            for (int i = 8; i >= 1; --i) {
                N -= 15 * f[15]/f[15-i+1];
                if (N < 0) {
                    N += 15 * f[15]/f[15-i+1];
                    Most = i;
                    break;
                }
            }
            init();
            for (int i = 1; i <= Most; ++i) {
                hash[digit[i]] = false;
                if (N - s[i] < 0) {
                    dfs(i, N, digit[i]-1);
                    break;
                }
            }
            for (int i = Most; i >= 1; --i) {
                if (digit[i] > 9) {
                    printf("%c", digit[i]-10+'A');
                }
                else {
                    printf("%d", digit[i]);    
                }
            }
            puts("");
        }
        return 0;    
    }
  • 相关阅读:
    UVA 11776
    NEFU 117
    hihocoder 1331
    NEFU 84
    虚拟机类加载机制
    动态规划 -- 01背包问题和完全背包问题
    动态规划 ---- 最长回文子串
    动态规划 ---- 最长公共子序列(Longest Common Subsequence, LCS)
    动态规划 ---- 最长不下降子序列(Longest Increasing Sequence, LIS)
    动态规划(Dynamic Programming, DP)---- 最大连续子序列和 & 力扣53. 最大子序和
  • 原文地址:https://www.cnblogs.com/Lyush/p/2629131.html
Copyright © 2020-2023  润新知