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 }