题意分析
给出一个数n,求一个数m,使得m >= n ,并且m 满足: m = ∑ 3 ^ i * x (x = 0 或者 x = 1 ),求出满足条件的最小的m
解题思路
两个题目都是一个题意,只是n的大小不同,所以就不用两个思路了
注意到,我们可以先令 m = ∑ 3 ^ i ,求出此时满足条件的最小的m,随后,因为m在三进制下,每一位都是1,那么如果我们从高位开始,不断地判断 m - 3 ^ i >= n ,如果满足,则令 m -= 3 ^ i ,此时我们删除了当前可以删除的最大数,这样将使得最终的结果最小,并且大于等于n
代码区
#include<iostream> #include<cstdio> #include<cstdlib> #include<algorithm> #include<cmath> #include<cstring> #include<queue> #include<string> #include<fstream> #include<vector> #include<stack> #include <map> #include <iomanip> #define bug cout << "**********" << endl #define show(x, y) cout<<"["<<x<<","<<y<<"] " #define LOCAL = 1; using namespace std; typedef long long ll; const ll inf = 1e18 + 7; const int Max = 2e5 + 10; ll fast_pow(ll a, ll n) { ll sum = 1; while (n != 0) { if (n & 1) sum = sum * a ; a = a * a ; n >>= 1; } return sum; } int main() { #ifdef LOCAL // freopen("input.txt", "r", stdin); // freopen("output.txt", "w", stdout); #endif int t; scanf("%d",&t); while(t--) { ll n; scanf("%lld",&n); ll sum = 0; int num = 0; while(sum < n) { sum += fast_pow(3,num); num++; } for(int i = num -1; i >= 0 ;i --) { ll lost = fast_pow(3,i); if(sum - lost >= n) sum -= lost; } printf("%lld\n",sum); } return 0; }