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;
}
posted @ 2019-10-23 21:08  YuhanのBlog  阅读(77)  评论(0编辑  收藏  举报