2017年8月18日提高组T1 袁绍的刁难

53 篇文章 0 订阅

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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值