Death to Binary? POJ - 2116
The group of Absurd Calculation Maniacs has discovered a great new way how to count. Instead of using the ordinary decadic numbers, they use Fibonacci base numbers. Numbers in this base are expressed as sequences of zeros and ones similarly to the binary numbers, but the weights of bits (fits?) in the representation are not powers of two, but the elements of the Fibonacci progression (1, 2, 3, 5, 8,... - the progression is defined by F0 = 1, F1 = 2 and the recursive relation F n = F n-1 + F n-2 for n >= 2).
For example 1101001 Fib = F0 + F3 + F5 + F6 = 1 + 5 + 13 + 21 = 40.
You may observe that every integer can be expressed in this base, but not necessarily in a unique way - for example 40 can be also expressed as 10001001 Fib. However, for any integer there is a unique representation that does not contain two adjacent digits 1 - we call this representation canonical. For example 10001001 Fib is a canonical Fibonacci representation of 40.
To prove that this representation of numbers is superior to the others, ACM have decided to create a computer that will compute in Fibonacci base. Your task is to create a program that takes two numbers in Fibonacci base (not necessarily in the canonical representation) and adds them together.
Input
The input consists of several instances, each of them consisting of a single line. Each line of the input contains two numbers X and Y in Fibonacci base separated by a single space. Each of the numbers has at most 40 digits. The end of input is not marked in any special way.
Output
The output for each instance should be formated as follows:
The first line contains the number X in the canonical representation, possibly padded from left by spaces. The second line starts with a plus sign followed by the number Y in the canonical representation, possibly padded from left by spaces. The third line starts by two spaces followed by a string of minus signs of the same length as the result of the addition. The fourth line starts by two spaces immediately followed by the canonical representation of X + Y. Both X and Y are padded from left by spaces so that the least significant digits of X, Y and X + Y are in the same column of the output. The output for each instance is followed by an empty line.
Sample Input
11101 1101
1 1
Sample Output
100101
+ 10001
-------
1001000
1
+ 1
--
10
题意:
以二进制的形式给出一串数列(例:11101),要求按照斐波那契数列的规律化为10进制,斐波那契数列1,2,3,5,8,13,21···,其标号分别为F0,F1,F2,F3···,化为十进制:1*1+2*0+3*1+5*1+8*1=17.数列11101的标准形式为:100101(中间不能有连续两个或两个以上的1出现即为标准形式,对每个十进制数字, 标准形式有且只有一种)。
要求输入两串数列,用空格隔开。输出两串数列的标准形式以及两串数列的相加结果,结果也要用标准形式表示。
分析:
∵F[n]=F[n−1]+F[n−2]
∵
F
[
n
]
=
F
[
n
−
1
]
+
F
[
n
−
2
]
∴
∴
我们知道如果存在了相邻到11,那么这两个连续到11一定可以用一个1表示(高一位)
∴
∴
都可以写成不连续的1的形式
我们采用贪心的方式解决,方法如下:
1. 将所给数字转化成十进制数,然后求出和
2. 将十进制数转化成fib形式
将十进制转化成fib形式方法如下:
1.
if num>=fib[i]→num−fib[i]→
i
f
n
u
m
>=
f
i
b
[
i
]
→
n
u
m
−
f
i
b
[
i
]
→
该位为1
2.
else if
e
l
s
e
i
f
字符串不是空
→
→
该位为0
仅仅这两步大家可能会有疑问,这样循环过程中
如果连续两次循环执行时,会不会连续两次都是num >= fib[i],这样字符串就有连续的1了?
下面说明这种情况不会出现:
F[n]=F[n−1]+F[n−2]
F
[
n
]
=
F
[
n
−
1
]
+
F
[
n
−
2
]
1—— 2 —— 3—— 5—— 8 —— 13—— 21
一、
if num>fib[i]
i
f
n
u
m
>
f
i
b
[
i
]
,但是一定小于
fib[i+1]
f
i
b
[
i
+
1
]
即 fib[i]<num<fib[i+1] f i b [ i ] < n u m < f i b [ i + 1 ]
∵fib[i−1]+fib[i]=fib[i+1] ∵ f i b [ i − 1 ] + f i b [ i ] = f i b [ i + 1 ]
∵fib[i]<num<fib[i+1] ∵ f i b [ i ] < n u m < f i b [ i + 1 ]
∴num−fib[i]<fib[i−1] ∴ n u m − f i b [ i ] < f i b [ i − 1 ]
这就证明了,减去当前fib数后,一定也小于前一个fib数,这就保证了不会出现连续的1。
二、如果直接等于fib那就更好说了,就当前位为1就结束了
这道题运用到算法简单,但是需要对菲波那契数列有深刻理解才行
code:
#include <iostream>
#include <cstring>
#include <cstdio>
#include <string>
using namespace std;
typedef long long ll;
const int MAXN = 55;
int n;
ll fib[MAXN];
string A,B;
void init(){
fib[0] = 1;
fib[1] = 2;
for(int i = 2; i < MAXN; i++){
fib[i] = fib[i-1] + fib[i-2];
}
}
ll toDec(string s){
ll ans = 0;
int len = s.length();
for(int i = 0; i < len; i++){
int val = s[len-i-1] - '0';
if(val)
ans += fib[i];
}
return ans;
}
string toFib(ll num){
string ans = "";
for(int i = 40; i >= 0; i--){
if(num >= fib[i]){
num -= fib[i];
ans += '1';
}
else if(ans != "")
ans += '0';
}
if(ans == "") ans = "0";
return ans;
}
int main(){
init();
while(cin >> A >> B){
ll a,b,c;
a = toDec(A);
b = toDec(B);
c = a + b;
//cout << a << b << c << endl;
string fa,fb,fc;
fa = toFib(a);
fb = toFib(b);
fc = toFib(c);
//cout << fa << fb << fc << endl;
int lena = fa.length();
int lenb = fb.length();
int lenc = fc.length();
cout << " ";
for(int i = 0; i < lenc-lena; i++){
cout << " ";
}
cout << fa << endl;
cout << "+ ";
for(int i = 0; i < lenc-lenb; i++){
cout << " ";
}
cout << fb << endl;
cout << " ";
for(int i = 0; i < lenc; i++){
cout << "-";
}
cout << endl;
cout << " " << fc << endl;
cout << endl;
}
return 0;
}