Codeforces 1249C2 Good Numbers (hard version)
思路:
1.贪心算法~;
2.对于任意一个正整数n
,它有两种可能:case1:
3a ≤ n ≤ (3a+1-1)/2 和 case2:
(3a+1-1)/2 < n < 3a+1(其中a为对应常数);
3. (3a+1-1)/2是如何求的呢,是30+31+…+3a,如果处在case2
中的数,那大于等于它的good number肯定就是3a+1啦;
4. 处在case1
中的数,那大于等于它的good number肯定有3a这个因子,我们只需将a保存下来,然后去递归求大于等于n-3a的good number就好啦;
5. 为了保证运行效率,我们可以提前将30 ~ 339的结果保存起来,也将(31-1)/2 ~ (339-1)/2的结果保存起来;
6. 次方运算就用循环算吧,用pow的话算339是不对的 ^ _ ^(至少我机器上算出来不对);
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll power_3[40];
ll cil[40];
vector<int> v;
void dfs(ll n){
if(n<=0) return;
int pos;
for(pos=0;pos<=39&&n>=power_3[pos+1];pos++);
if(n>cil[pos]) v.push_back(pos+1);
else{
v.push_back(pos);
dfs(n-power_3[pos]);
}
}
int main(){
int q;
cin>>q;
ll power=1;
for(int i=0;i<=39;i++,power*=3) power_3[i]=power;
for(int i=0;i<=38;i++) cil[i]=(power_3[i+1]-1)>>1;
for(int i=0;i<q;i++){
ll n;
cin>>n;
v.clear();
dfs(n);
ll ans=0;
for(auto e:v) ans+=power_3[e];
cout<<ans<<'\n';
}
return 0;
}