您的位置:首页 > 其它

UVa Problem 10183 How Many Fibs? (斐波那契计数)

2011-05-31 19:52 841 查看
// How Many Fibs? (斐波那契计数)
// PC/UVa IDs: 110601/10183, Popularity: B, Success rate: average Level: 1
// Verdict: Accepted
// Submission Date: 2011-05-30
// UVa Run Time: 0.012s
//
// 版权所有(C)2011,邱秋。metaphysis # yeah dot net
//
// 很遗憾,不能使用斐波那契数的封闭形式来帮助解决此题,因为封闭形式只能大概估计,有 -1 到 1 的
// 误差。只能老老实实实现大数加法了。这里使用了一点小技巧,定义了一个向量 vector < stri
// ng > fibs,保存计算得到的斐波那契数,预先计算到有 100 位数的斐波那契数,采用字符串比较的
// 方式找到第一个大于等于 a 和最后一个小于等于 b 的斐波那契数在数组中的位置,统计之间包含的斐波
// 那契数即可。

#include <iostream>
#include <sstream>
#include <vector>

using namespace std;

#define UPBOUND 101

vector < string > fibs;

// 比较两个斐波那契数的大小,数位存放在f1和f2中,其中f1的数位是按高位到低位存放,f2的数位
// 是按低位到高位存放。f1大于f2返回1,小于返回-1,等于返回0。
int fibs_compare(string f1, string f2)
{
if (f1.length() != f2.length())
return f1.length() > f2.length() ? 1 : (-1);

for (int i = 0, j = f2.length() - 1; i < f1.length(); i++, j--)
if (f1[i] != f2[j])
return f1[i] > f2[j] ? 1 : (-1);

return 0;
}

// 根据前两个斐波那契数产生下一个斐波那契数,数位逆序存放于字符串变量f1和f2,最终结果也逆序存放。
string fibs_add(string f1, string f2)
{
// 前后两个斐波那契数有以下长度关系:f1.length() <= f2.length()。
string tmp;
int carry = 0;

for (int i = 0; i < f1.length(); i++)
{
carry = (f1[i] - '0') + (f2[i] - '0') + carry;
char c = '0' + carry % 10;
tmp.append(1, c);
carry = carry / 10;
}

for (int i = f1.length(); i < f2.length(); i++)
{
carry = (f2[i] - '0') + carry;
char c = '0' + carry % 10;
tmp.append(1, c);
carry = carry / 10;
}

if (carry)
tmp.append(1, '1');

return tmp;
}

// 填充斐波那契数表,直到计算出具有101位数的斐波那契数为止。
void fill_fibs()
{
string f1 = "1", f2 = "2";

fibs.push_back(f1);
fibs.push_back(f2);

while (f2.length() < UPBOUND)
{
string tmp = fibs_add(f1, f2);
f1 = f2;
f2 = tmp;
fibs.push_back(f2);
}
}

int main(int ac, char *av[])
{
// 填充斐波那契数表。
fill_fibs();

string a, b, line;
while (getline(cin, line), line.length())
{
istringstream iss(line);
iss >> a >> b;

if (a == "0" && b == "0")
break;
else
{
// 找到大于等于a的斐波那契数在fibs数组的位置。
int start, end;
for (int i = 0; i < fibs.size(); i++)
{
if (a.length() > fibs[i].length())
continue;

if (fibs_compare(a, fibs[i]) <= 0)
{
start = i;
break;
}
}

// 找到小于等于b的斐波那契数在fibs数组的位置。
for (int i = fibs.size() - 1; i >= 0; i--)
{
if (b.length() < fibs[i].length())
continue;

if (fibs_compare(b, fibs[i]) >= 0)
{
end = i;
break;
}
}

// 输出总个数。
cout << (end - start + 1) << endl;
}
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: