感觉这种方法比较巧妙,且易于理解。贪心求,从最大位遍历,能减就减
#include <bits/stdc++.h>
typedef long long ll;
using namespace std;
#define debug(x, y) cout <<x<<" "<<y<<endl
#define nl cout << endl
#define inf 0x3f3f3f3f
const int maxn = 2e5+10;
ll ma, d;
void init()
{
d = 1;
ma = 0;
while(ma < 1e18) {
ma += d;
d *= 3;
}
}
int main()
{
int t;
init();
scanf("%d", &t);
while(t--) {
ll n;
scanf("%I64d", &n);
ll temp = d;
ll ans = ma;
while(temp)
{
if(ans-temp >= n) ans -= temp;
temp /= 3;
}
printf("%I64d\n", ans);
}
return 0;
}
第二种方法
这种方法就是先转成三进制,找位上为2的数,把之前的变成0,后一位加一,有限次数内一定能完成找到需要的数。
#include <bits/stdc++.h>
typedef long long ll;
using namespace std;
#define debug(x, y) cout <<x<<" "<<y<<endl
#define nl cout << endl
#define inf 0x3f3f3f3f
const int maxn = 2e5+10;
const int N = 2e5+10;
int main()
{
int t;
scanf("%d", &t);
while(t--) {
ll n;vector<int> pre;
scanf("%I64d", &n);
while(n)
{
pre.push_back(n%3);
n /= 3;
}
pre.push_back(0);
pre.push_back(0);
for(int i = 0; i <= 60; ++i)
{
int ans = -1;
for(int j = 0; j < (int)pre.size(); ++j)
if(pre[j]==2) ans = j;
if(ans == -1) break;
for(int j = 0; j <= ans; ++j) pre[j] = 0;
pre[ans+1]++;
}
ll ans = 0;
ll d = 1;
for(int i = 0; i < (int)pre.size(); ++i) {
ans += d*pre[i];
d *= 3;
}
printf("%lld\n", ans);
}
return 0;
}