Hexadecimal Numbers(POJ-1715)(排列组合)

8 篇文章 0 订阅
7 篇文章 0 订阅

文章目录

题目

Vjudge
POJ
题目大意:
求第 n n n 大的位数小于8位的无重复数字的16进制数(用0~ 9,A~F表示),
i n in in
11
o u t out out
FEDCBA87

思路

我们发现长度为 l e n len len 的所有方案为 A 16 l e n A_{16}^{len} A16len(允许前导0)
然后我们从高位到低位确定位数
如果前面已经选了 x x x 个位数,那么我们发现长度为 l e n len len 的所有方案为 A 16 − x l e n A_{16-x}^{len} A16xlen(允许前导0)
那么扫一遍即可,注意前导0不要输出

代码

#include<set>
#include<map>
#include<cmath>
#include<stack>
#include<queue>
#include<cstdio>
#include<vector>
#include<climits>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define LL long long
#define ULL unsigned long long
int read(){
	int f=1,x=0;char c=getchar();
	while(c<'0'||'9'<c){if(c=='-')f=-1;c=getchar();}
	while('0'<=c&&c<='9') x=(x<<3)+(x<<1)+(c^48),c=getchar();
	return f*x;
}
#define MAXN 20
#define INF 0x3f3f3f3f
int A(int n,int m){
	if(!m) return 1;
	int ret=1;
	for(int i=n;i>=n-m+1;i--)
		ret*=i;
	return ret;
}
map<int,char>Map;
int S[MAXN+5];
int main(){
	int n=read();
	for(int i=0;i<=5;i++)
		Map[i+10]=i+'A';
	for(int i=0;i<=9;i++)
		Map[i]=i+'0';
	bool vis[20]={0},flag=0;
	int cnt=0;
	for(int i=1;i<=8;i++){
		int t=15;
		while(t>=1){
			if(vis[t]){
				t--;
				continue;
			}
			int tmp=A(15-cnt,8-i);
			if(n<=tmp){
				vis[t]=1;
				break;
			}
			n-=tmp;
			t--;
		}
		S[i]=t;
		if(t!=0||flag) cnt++;
		if(t!=0) flag=1;
	}
	flag=0;
	for(int i=1;i<=8;i++)
		if(S[i]!=0||flag)
			putchar(Map[S[i]]),flag=1;
	puts("");
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值