Codeforces--C2. Good Numbers (hard version)

题目链接http://codeforces.com/contest/1249/problem/C2。这是道进制转换题,我们的目的是找到最小的一个每个位都是1的三进制数来表示一个十进制数n。做法是,先将n转换为一个三进制数,然后对当前位加上低位的进位大于等于2的位置0并进位,这一步需要注意的是,当前位如果产生进位,需要把该位的低位都给置0,这样才能保证重构后的数最小。

此外,需要注意的是,在利用重构数组计算10进制数的时候,不能用pow函数,因为,pow对3的38次幂是无法计算的,会发生溢出,需要自己写一个。

 1 #include<bits/stdc++.h>
 2 
 3 using namespace std;
 4 
 5 int str[100];
 6 
 7 int intToA(long long n, long long radix){
 8     int len = 0;
 9     if(!n){
10         str[0] = 0;
11         return 1;
12     }
13     long long tmp = n;
14     do{
15         tmp /= radix;
16         str[len++] = n - radix * tmp;
17         n = tmp;   
18     }while(n);
19     return len;
20 }
21 
22 long long solve(long long num){
23     int n = intToA(num, 3);
24     int c = 0;
25     for(int i=0;i<n;i++){
26         if(str[i] + c >= 2){
27             fill(str, str + i, 0);
28             str[i] = 0;
29             c = 1;
30         }
31         else{
32             str[i] += c;
33             c = 0;
34         }
35     }
36     long long j = 1;
37     long long sum = 0;
38     if(c){
39         for(int i=0;i<n;i++){
40             j *= 3;
41         }        
42         return j;
43     }
44     for(int i=0;i<n;i++){
45         sum += (long long) (str[i] * j);
46         j *= 3;
47     }
48     return sum;
49 }
50 
51 int main(){
52     int q;
53     scanf("%d", &q);
54     while(q--){
55         long long n;
56         cin>>n;
57         cout<<solve(n)<<endl;
58     }
59     return 0;
60 }

 

posted @ 2019-10-27 12:04  守功  阅读(455)  评论(0编辑  收藏  举报