题目 | 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; }
|