天平2——三进制的货币系统

Description:

        J王国的货币非常奇怪,面值都是3的若干次方 即面值为1,3,9,27,81......... 国王现在发现这些货币,每种只有一张这样的钱。 于是国王发现从这些钱中先任意组合,再加钱的面值相加得到一个总和的话:

则面值最小的为空集,也就是说一张钱也不要

面值第2小的为{1},总和为1

面值第3小的为{3},总和为3

面值第4小的为{1,3},总和为4

面值第5小的为{9},总和为9

面值第6小的为{1,9},总和为10

面值第7小的为{3,9},总和为12

现在问你面值第K小的,它是选择了哪些钱币?

Input

一行给出一个数字k,1<N<=10^6

Output

输出若干行,每行输出一个数字,数字从小到大。

思路:

        因题目限定为每种钱币只能是一张,也就是说某个数转为三进制后,只要找出该数中每位数字上的“1”,然后进行以3为底的幂次运算,即可达到题目要求的钱币组合。但问题的关键是如何找出第K小的数?同样由于题意,每种钱币只能使用1张或0张的组合,这就将问题变成了:一个n位的数,每位数只能使用0或1的排列组合方式,从小到大排列就是0、1、10、11、100、101......这就相当于是从小到大的二进制排列。刚好符合题意中的第K小的数,需要注意的是0变成了第一小,那么第K小就是K-1。分解K-1为二进制序列,再将该序列不同数位上的“1”进行以3为底、数位顺序为幂次进行幂运算即为答案!

AC代码:

#include<bits/stdc++.h>
using namespace std;
int pow(int a, int b) { //快速幂函数
	int res =  1;
	while (b > 0) {
		if (b & 1) res *= a;
		b >>= 1;
		a *= a;
	}
	return res;
}
string Binary(int num) { //位操作将一个数分解为二进制数为字符串形式
	string bit, s = "";
	while (num > 0) {
		bit = to_string( num & 1); // 获取最低位
		s += bit ;
		num >>= 1; // 右移一位
	}
	return s;
}
int main() {
	int n;
	cin >> n;
	string bStr = Binary(n - 1); //返回逆序的二制字符串
	for (int i = 0; i <= bStr.length(); ++i) //计算3的幂次
		if (bStr[i] == '1')
			cout << pow(3, i) << endl;
	return 0;
}

  • 8
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值