poj 1715 Hexadecimal Numbers

 

题目

Hexadecimal Numbers (hex)

问题摘要

 

解法1

源程序

hex.dpr

解法核心

枚举+组合数学

特殊数据结构

N/A

复杂度

O(Len*Digit), Here Digit = 16

状态

Accepted

作题日期

2006-6-3

解法描述

首先确定数字串的长度Len:从大到小枚举Len,每个Len下有15*P(15, Len-1)个数字串。每次用这个个数扣除输入的序数Count,直到序数Count扣为负数时停止,就确定了长度Len。

 

然后从高位到低位,从大到小确定每位数字:设当前确定的数字为第i位,则第i位的任何一个取值,都有P(16 - (Len - i + 1), i - 1)个数字串将已确定的第1到i位作为前缀。每次用这个个数扣除输入的序数Count,直到序数Count扣为负数时停止,就确定了当前位的数字。

 

注意不能有前导0。

View Code
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<queue>
#include<set>
#include<map>
#include<cstring>
#include<vector>
#include<string>
#define LL long long
using namespace std;
char num[16]={ '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
char ans[8];
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 visit[16] = {0},Head = false;
    int uselen = 0,countv;
    for( int i = 1 ; i <= 8 ; i ++  )//从高位到低位 
    {
         int cnt = 15;
         while( cnt )
         {
             if( !visit[cnt] )//筛选已被选的 
             {//如果countv小于count,代表改位还可以下降以为在去比较 
                  if( (countv = Axy( 16 -1 - uselen , 8 - i ))<count )
                       count -= countv;
                  else
                  {//大于代表改位不能在下降了 
                     visit[cnt] = true;
                     break;        
                  }        
             }
             cnt --;           
         }    
         ans[i] = num[cnt];
         if( Head || ans[i] !='0' ) uselen ++;//如果是前导0代表选的个数还没变; 
         if( ans[i] != '0' ) Head = true;
    }    
}
int main(  )
{
    int count;
    while( scanf( "%d",&count )==1 )
    {
          bool Head = false;
          Solve( count );
          for( int i = 1; i <= 8 ; i ++ )
          {
              if( Head || ans[i]!='0' )
              {
                  printf( "%c",ans[i] );
                  Head = true;
             }
          }
          if( !Head ) printf( "0" );
          puts( "" );
    }
    return 0;    
}

 

转载于:https://www.cnblogs.com/bo-tao/archive/2012/08/08/2628964.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值