Description
黄巾之乱后,郭嘉到了袁绍的统辖地区,结果袁绍想给我们的郭嘉大大一个下马威,且正值他招募将领的时候,于是乎,袁绍就让郭嘉大大去替他招募将领。
这时候有很多很多的将领到袁绍处报到(别人家底厚,四世三公哪~~),每个将领的编号依次为1、2、3……N,第i个将领的武力值为3^(i-1)。
袁绍需要我们的郭嘉大大招纳任意个将领,而郭嘉选中的将领有一个“总武力值”为各个将领的武力值之和。例如:郭嘉这一次招募了第一个将领和第三个将领,那么“总武力值”为1+9=10。
袁绍想知道,他可以获得的第k大的“总武力值”是多少,请你帮助我们的郭嘉大大告诉袁绍这个第k大的“总武力值”。
从文件中读入k,输出郭嘉能够获得的,第k大的“总武力值”。
Input
数据包含n+1行,第一行读入n(n≤100)。以下n行每行包含一个k。
Output
输出包含n行,每行输出一个对应的结果。
Source
BMP
Solution
考虑当前第i大的武力值为k,那么k在3进制下一定是仅存在0、1的。
每次我们可以找一个最右边的0变成1,在它右边全变成0,显然这个生成的新武力值是最小的。举个栗子,1000>0111
这样子就等同于二进制下的加1了,i转成二进制再按照每位对应3的次方相加即可
Code
#include <stdio.h>
#define ll long long
#define N 64
ll p[N];
inline ll read() {
ll x = 0; char ch = getchar();
while (ch < '0' || ch > '9') {ch = getchar();}
while (ch <= '9' && ch >= '0') {x = x * 10 + ch - '0'; ch = getchar();}
return x;
}
inline void writeln(ll x) {
int prt[64] = {};
do {prt[++ prt[0]] = x % 10;}while (x /= 10);
for (int i = prt[0]; i >= 1; i -= 1) {putchar((char)(prt[i]+'0'));}
puts("");
}
int main(void) {
for (ll i = 0, j = 1; i <= 63; i += 1, j *= 3) {p[i] = j;}
ll n = read();
while (n --) {
ll k = read();
ll ans = 0;
ll cnt = 0;
do {ans += (k % 2)?p[cnt]:0; cnt += 1;}while(k /= 2);
writeln(ans);
}
return 0;
}