BigNums——HDUOJ 1316 - How Many Fibs?(斐波那契个数 + 二分法 + 预处理)
2017-10-21 17:54
323 查看
原题:
Problem DescriptionRecall the definition of the Fibonacci numbers:
f1 := 1
f2 := 2
fn := fn-1 + fn-2 (n >= 3)
Given two numbers a and b, calculate how many Fibonacci numbers are in the range [a, b].
Input
The input contains several test cases. Each test case consists of two non-negative integer numbers a and b. Input is terminated by a = b = 0. Otherwise, a <= b <= 10^100. The numbers a and b are given with no superfluous leading zeros.
Output
For each test case output on a single line the number of Fibonacci numbers fi with a <= fi <= b.
Sample Input
10 100
1234567890 9876543210
0 0
Sample Output
5
4
这题有点坑:
1. F1 = 1,F2 = 2
2. 考虑输入的第一个数有可能为0
3. 考虑输入相同的数(如:1 1或者4 4)
解题思路:
1. 使用string比直接char[]节省内存占用,有c++库函数,用起来方便
2. 预处理:通过string数组先将前500个斐波那契数字算好,存起来
3. 二分法:最后head指针和tail指针相差 1 时,可以直接返回mid值(即head的值【head = mid】)注意:二分法后获得的值sum[mid] <= TestNum(原来要寻找的值)
代码:
#include<stdio.h> #include <string> #include <iostream> using namespace std; const int MAXFIB = 501;//斐波那契个数 string sum[MAXFIB]; void Add(int num) { int i; int LengthOfTow = sum[num - 1].length() - sum[num - 2].length();//两个数相差的长度 int temp; short CarryBit = 0;//进位 for (i = sum[num - 2].length() - 1; i >= 0; i--)//从两个数中小的数[F(n-2)]开始,再从**string**数组元素倒退,逐个加法进位 { temp = (sum[num - 2][i] - '0') + (sum[num - 1][i + LengthOfTow] - '0') + CarryBit; CarryBit = temp / 10; sum[num] = char((temp % 10) + '0') + sum[num]; } for(i = i + LengthOfTow; i >= 0; i--)//从两个数中大的数[F(n-1)]开始进位 { temp = (sum[num - 1][i] - '0') + CarryBit; CarryBit = temp / 10; sum[num] = char((temp % 10) + '0') + sum[num]; } if (CarryBit != 0)//两数相加,总数位数最多是大数位数+1 { sum[num] = char(CarryBit + '0') + sum[num]; } } void PreFibonacci()//预处理 { sum[0] = "1"; sum[1] = "2"; int i; for (i = 2; i < MAXFIB; i++) { Add(i); //cout <<i << " "<< sum[i] << endl; } } int CompareSiza(string a, string b)//两个string 比较大小//a大返回true,b大返回false { if (a.length() != b.length()) { return a.length() > b.length() ? 1 : -1;//通过长度判断 } else//从首位开始判断 { int length = a.length() - 1; int i = 0; for (; i <= length; i++) { if ((a[i] - '0') == (b[i] - '0'))//该位数字相等 { continue; } else { return (a[i] - '0') > (b[i] - '0') ? 1 : -1; } } return 0;//两数相等 } } int BinarySearch(string TestNum)//二分查找 { int head = 0; int tail = MAXFIB; int mid = (head + tail) / 2; int CompareResult; while (mid != 0||mid != MAXFIB) { CompareResult = CompareSiza(sum[mid], TestNum); if (1 == CompareResult)//mid > testnum { tail = mid; }else if (-1 == CompareResult) { head = mid; }else { return mid;//两数相等(找到) } mid = (head + tail) / 2; if (head + 1 == t 4000 ail)//二分结束 { return mid; } } } int main() { PreFibonacci();//预处理 string a, b; int aPosition; int bPosition; while (cin >> a && cin >> b && ((a[0] - '0') + (b[0] != '0'))!= 0) { if (a[0] == '0')//第一个数为0 { aPosition = -1; } else { aPosition = BinarySearch(a); if (CompareSiza(sum[aPosition],a) == 0)//判断第一个数是否在斐波那契数列中,是的话需要退一格 { aPosition--; } } bPosition = BinarySearch(b); if (bPosition == aPosition)//两数相等 { if (CompareSiza(sum[aPosition], a) == 0)//属于斐波那契数列 { printf("1\n"); }else { printf("0\n"); } }else//两数不相等 { printf("%d\n", bPosition - aPosition); } } }
相关文章推荐
- HDUOJ - 1316 How Many Fibs?
- HDUOJ - 1316 How Many Fibs?
- JAVA hdu 1316 How Many Fibs?(高精度)
- 第四届图灵杯->How Many Fibs?(1316)
- HDOJ 1316 How Many Fibs?
- hdu 1316 How Many Fibs?(大数,二分)
- HDU 1316 How Many Fibs?
- 杭电 1316 How Many Fibs?
- 杭电OJ(HDOJ)1316题:How many Fibs?(大数操作——比较)
- Java 大数之大数高精度斐波那契 UVA_10579&&HDU1316 How many Fibs?
- hdu 1316 How Many Fibs?
- hdu 1316 How Many Fibs?
- How Many Fibs_hdu_1316(大数).java
- UVa Problem 10183 How Many Fibs? (斐波那契计数)
- hdu 1316 How Many Fibs? (模拟高精度)
- HDOJ 1316 How Many Fibs?
- hdu1316 How Many Fibs?
- HDU 1316 How Many Fibs?(递推,大数相加)
- 杭电1316(How Many Fibs?)
- hdu 1316 How Many Fibs?