2018湘潭大学程序设计竞赛【D】
题目链接:https://www.nowcoder.com/acm/contest/105/D
题意:就是数的fib表示方法。按权展开,又按二进制算出结果输出。
题解:贪心和数论吧。找到跟数最接近的fib的最大数,依次找下去就行。
贪心的证明看这个blog,写的很清楚https://blog.csdn.net/mobius_strip/article/details/46483605
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <cmath> 5 #define ll long long 6 using namespace std; 7 8 string solve(int n){ 9 ll fib[1000]; 10 fib[0] = 1; 11 fib[1] = 2; 12 int i,j; 13 for( i = 2; i < 1000; i++){ 14 fib[i] = fib[i-1] + fib[i-2]; 15 if(fib[i] > n) { 16 j = i; 17 break; 18 } 19 } 20 21 string s; 22 for( i = j - 1 ; i >= 0; i--){ 23 int sum=0; 24 for(int k = 0 ; k < i; k++) 25 sum += fib[k]; 26 27 28 if(sum >= n) 29 s += '0'; 30 else 31 s += '1', n -= fib[i]; 32 } 33 return s; 34 } 35 36 int main(){ 37 int t; 38 scanf("%d",&t); 39 while(t--){ 40 int n; 41 scanf("%d",&n); 42 43 string s = solve(n); 44 45 ll x = 1; 46 ll sum = 0; 47 for(int i = s.size() - 1 ; i >= 0; i--){ 48 sum += (s[i] - '0') * x; 49 x = x * 2; 50 } 51 cout << sum << endl; 52 } 53 return 0; 54 }