1715 Hexadecimal Numbers 给出十六进制系统,每一个16进制的数对应于一个10进制的数,16进制的数最长8位,然后按10进制从大到小排序。 首位不能为零。 给出n,要求第n大的16进制数。

Hexadecimal Numbers
Time Limit: 1000MS Memory Limit: 10000K
Total Submissions: 1555 Accepted: 373

Description

The base of the hexadecimal system is 16. In order to write down numbers in this system one uses 16 digits 0,1,...,9,A,B,C,D,E,F. The capital letters A,..,F stands for 10,..,15, respectively. For instance the value of the hexadecimal number CF2 is 12 * 162 + 15 * 16 + 2 = 3314 in the decimal system. Let X be the set of all positive integers whose hexadecimal representations have at most 8 digits and do not contain repetitions of any digit. The most significant digit in such a representation is not zero. The largest element in X is the number with the hexadecimal representation FEDCBA98, the second largest is the number FEDCBA97, the third is FEDCBA96 and so forth.
Write a program that: finds the n-th largest element of X;

Input

The first line of the file standard input contains integer n in the decimal representation. n does not exceed the number of elements of X.

Output

Your program should output the n-th largest element in X in the hexadecimal representation.

Sample Input

11

Sample Output

FEDCBA87
#include "iostream"
#include "cstring"
#include "cstdio"
using namespace std;
const int N = 101;
#define LLD __int64
char str[N];
LLD dig[9],lmax;
int vis[N],res[N];
int n,m;
LLD fac(int n,int m)
{
    //p(n,m)=n(n-1)(n-2)……(n-m+1)= n!/(n-m)!(规定0!=1).
 if(m==0) return 1;
    int i,j,t;
    LLD cnt=1;
    t=n;
    while(1)
    {
        cnt=cnt*t;
        if(t==n-m+1) break;
        t--;
    }
    return cnt;
}
void solve()
{
   int i,j,t,ud=0;
   LLD tmp;
   bool flag=false;
   memset(vis,0,sizeof(vis));
   for(i=1;i<=8;i++)//从高位找起
   {
       t=15;//从高找起
       while(t>=1)
       {
          if(!vis[t])//每个数只能出现一次
          {
              tmp=fac(16-1-ud,8-i);//高位已经确定时,剩下的组合有tmp种 ud表示已经有的位数
              if(tmp<n)//若组合数还小于当前n的话则减去tmp继续算该位等于t--时的个数
              n=n-tmp;
              else//否则该位就是t 标记跳出
              {
                  vis[t]=1;
                  break;
              }
          }
          t--;
       }
       res[i]=t;
       if(t!=0||flag)  ud++;//首位去0
       if(t!=0) flag=true;
   }
}
void print()
{
    int i,j;
    char ch;
    bool flag=false;
    for(i=1;i<=8;i++)
     if(res[i]!=0||flag)
     {
         if(res[i]<10) printf("%d",res[i]);
         else {ch='A'+res[i]-10;
         printf("%c",ch);
         }
         flag=true;
     }
  printf("/n");
}
int main()
{
    //cout<<fac(16,8)<<endl;
    while(scanf("%d",&n)!=EOF)
    {
       solve();
       print();
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值