该题数值较大,可以转为三进制用数组保存每个位的数。从最高位往低位遍历,遇到1和0跳过,遇到2说明该数不满足题意,要找到最小的数,应将该位置的2和比该位低的位变成0,然后往高位遍历遇到1将其变为0,直到遇到0,把0变为1即为最小的数。因为遇到2一定需要往高位进位,不然无法消去该位上的2,所以将低位全部清0,找到第一个高位的0变为1即可,遇到1进位会变成2依旧需要往高位进位所以将其变为0。
参考大佬的代码
#include<iostream>
#include<cstring>
using namespace std;
typedef long long ll;
int a[1000];
int r;
//转成三进制用数组保存
void to3(ll n){
r = 0;
while(n){
a[r++] = n%3;
n /= 3;
}
//增加一个最高位以免位数不足
a[r] = 0;
return;
}
//转回十进制输出
ll to10(){
ll sum = 0;
ll cur = 1;
for( int i = 0 ; i <= r ; ++i ){
if(a[i]){
sum += cur;
}
cur *= 3;
}
return sum;
}
int main(){
int t;
cin >> t;
while(t--){
ll n;
memset(a,0,sizeof(a));
cin >> n;
to3(n);
for( int i = r ; i >= 0 ; --i ){
if(a[i] == 2){
for( int j = i ; j >= 0 ; --j ){
a[j] = 0;
}
for( int k = i+1 ; k <= r ; ++k ){
if(a[k] == 1){
a[k] = 0;
}
else if(a[k] == 0){
a[k] = 1;
break;
}
}
break;
}
}
cout << to10() << endl;
}
return 0;
}