2018 Xiangtan University Programming Competition-----Fibonacci System


Fibonacci number is a very famous number sequence, its formula is f(n)=f(n-1)+f(n-2), f(0)=1, f(1)=2. 
We can express any number x as the sum of several different Fibonacci numbers, say 14 = 13+1 = 8+5+1 = 8+3+2+1.
If the Fibonacci sequence is used as the bit weight of the number, that is, f(i) is used as the bit weight of the i-th bit, the coefficient of each bit can only be 0 or 1, thus obtaining a 01 string. For example, 14 can be represented as 100001, 11001, 10111. Let's take this 01 string as binary, and then convert it into decimal, it becomes 33, 25, 23. To avoid ambiguity, we will use the smallest value, 23.
 Please follow this procedure to calculate the decimal integer obtained by the above conversion process.

Enter description:

The first line is an integer T (1 ≤ T ≤ 10000), representing the number of samples.
One example per line thereafter is a positive decimal integer x (1 ≤ x ≤ 10 9 ).

Output description:

Output one sample result per line.
Example 1

enter

5
1
10
100
1000
1000000000

output

1
14
367
10966
4083305275263

Idea: first list the Fibonacci numbers within 1e9 and their prefixes and sums

Example: Fibonacci: 1 2 3 5 8 13 21 34. .. .. .. .. .. ..

       Prefix Sum: 1 3 6 11 19 32.. . . . . . Stop when the prefix sum is greater than 1e9

14 = 1 + 2 + 3 + 8 -------11101 (since 5 is not added, so 5 is 0 here and 1 elsewhere)

Traverse the prefix sum to find the first number n greater than the input, record it as ans, and record the current position cnt

Because what is required is the smallest number when the 01 string is converted into decimal, so we can traverse cnt in reverse order, and then continue to judge 

Take a book array to record that it is 1 or 0 at this time;

The reason for the reverse order is that the higher the binary number, the larger the number, so the minimum value can be obtained by replacing the previous 1 with 0 as much as possible.

Code below:

#include <stdio.h>
#include <math.h>
#include <iostream>
#include <cstring>
using namespace std;
intmain()
{
	long long int t,x,book[100],ans,cnt;
	long long int fib[100],sum[100];
	fib[0] = 1;
	fib[1] = 2;
	sum[0] = 1;
	sum[1] = 3;
	for(int i = 2; ; i++)
	{
		fib[i] = fib[i-1]+fib[i-2];
		sum[i] = sum[i-1]+fib[i];
		if(sum[i] >1e9)
		{
			break;
		}
	}
	scanf("%lld" , &t);
	while(t--)
	{
		memset(book,0,sizeof(book));
		scanf("%lld" , &x);
		for(int i = 0 ; i < 66 ; i++)
		{
				book[i] = 1;
			if(x <= sum[i])
			{
				ans = sum[i];
				cnt = i;
				break;
			}
		}
		long long int answer = 0;
		if(x == ans)
		{
			for(int i = cnt ; i>= 0 ; i--)
			{
				answer += (long long)book[i]*pow(2,i);
			}
		}
		else
		{
			for(int i = cnt ; i >= 0 ; i--)
			{
				if( (ans - fib[i]) < x)
				{
					continue;
				}
				else if( (ans-fib[i]) > x )
				{
					ans -= fib[i];
					book[i]=0 ;
					continue;
				}
			else if((ans-fib[i])==x  )
				{
					ans -= fib[i];
					book[i]=0;
					break;
				}
			}
			for(int i = cnt ; i>= 0 ; i--)
			{
				answer += (long long)book[i]*pow(2,i);
			}
		}
			printf("%lld\n" , answer);
	 }

	return 0;
}

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326710858&siteId=291194637