• poj 1715 Hexadecimal Numbers 排列组合


     1 /**
     2 大意: 给定16进制数的16个字母,,求第k大的数,,要求数的长度最大为8.,并且每个数互不相同。
     3 思路: 从高到低挨个枚举,每一位能组成的排列数 ,拿最高位来说,能做成的排列数为15*A(15,len-i)
     4           第二位 A(14,len-2)。。这样就可以找到k大的数的长度
     5 接下来 。找第k大的数。同上理 ,挨个枚举每一位即可。。若加上该位的排列数大于k,则该位就是这个数,继续枚举下一位
     6 **/
     7 
     8 /**  大神思路
     9 首先确定数字串的长度Len:从大到小枚举Len,每个Len下有15*P(15, Len-1)个数字串。每次用这个个数扣除输入的序数Count,直到序数Count将扣为负数时停止,就确定了长度Len。
    10  
    11 然后从高位到低位,从大到小确定每位数字:设当前确定的数字为第i位,则第i位的任何一个取值,都有P(16 - (Len - i + 1), i - 1)个数字串将已确定的第1到i位作为前缀。每次用这个个数扣除输入的序数Count,直到序数Count将扣为负数时停止,就确定了当前位的数字。
    12  
    13 注意不能有前导0。
    14 **/
    15 #include <iostream>
    16 
    17 using namespace std;
    18 char num[16]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
    19 int ans[10];
    20 
    21 int Axy(int x,int y){
    22     int res =1;
    23     if(y==0)
    24         return 1;
    25     while(y--){
    26         res *= x;
    27         x--;
    28     }
    29     return res;
    30 }
    31 
    32 void solve(int count){
    33     bool vis[16]={0},head = false;
    34     int uselen = 0,countv;
    35     for(int i=1;i<=8;i++){
    36         int cnt = 15;
    37         while(cnt){
    38             if(!vis[cnt]){
    39                 if((countv = Axy(16-1-uselen,8-i))<count){
    40                     count -= countv;
    41                 }else{
    42                     vis[cnt] = true;
    43                     break;
    44                 }
    45             }
    46             cnt--;
    47         }
    48         ans[i] = num[cnt];
    49         if(head||ans[i]!='0') uselen++;
    50         if(ans[i]!='0') head = true;
    51     }
    52 }
    53 
    54 int main()
    55 {
    56     int cnt;
    57     while(cin>>cnt){
    58         bool head = false;
    59         solve(cnt);
    60         for(int i=1;i<=8;i++){     
    61             if(head||ans[i]!='0'){     //去除前导0
    62                 cout<<(char)ans[i];
    63                 head = true;
    64             }
    65         }
    66         if(!head)     // 若全为0 ,则输出0
    67             cout<<0;
    68         cout<<endl;
    69     }
    70     return 0;
    71 }
  • 相关阅读:
    POJ-3254 + POJ-1185 状压DP入门题
    POJ-3667 线段树区间合并入门题
    HDU-4507 数位DP 记录一个毒瘤错误orz
    HDU-4734 F(x)数位dp
    HDU-3709 Balanced Number 数位dp+枚举
    分块入门 LibreOJ分块九题
    HDU-4389 X mod f(x) && 2018上海大都会邀请赛J 数位dp
    HDU-3038 How Many Answers Are Wrong (带权并查集)
    Codeforces 608B Hamming Distance Sum (前缀和)
    (二十六 )数据库:水平切分,数据库秒级扩容!
  • 原文地址:https://www.cnblogs.com/Bang-cansee/p/3724108.html
Copyright © 2020-2023  润新知