题目来源:http://poj.org/problem?id=2413 / http://acm.hdu.edu.cn/showproblem.php?pid=1316
How many Fibs?
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 10742 | Accepted: 3979 |
Description
Recall 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<=10100. 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
Source
题意: 求区间[a,b] 上Fibonacci 数的个数。
题解: 大数(用了压位高精度)+打表
PS: 我下面这个代码要在杭电上提交,编译器得选C++ 才给过 在POJ上G++是可以过的=-= 为此我还在知乎上提问了http://www.zhihu.com/question/27057931/answer/35115406?group_id=527458265756372992
AC代码:
#include<iostream> #include<fstream> #include<string> #include<cmath> #define carry 100000000 #define maxn 600 using namespace std; ifstream fin("in.txt"); ofstream fout("t.txt"); #define cin fin #define cout fout string num[maxn]; void str2num(string &x, int *num){ int len = x.size(), pos = 0; for (int i = 1; i <= len / 8; i++){ string temp = x.substr(len - 8 * i, 8); for (int i = 0; i<8; i++) num[pos] += (temp[7 - i] - '0')*(int)pow(10.0,double(i)); pos++; } int left = len % 8; if (left){ for (int i = 0; i < left; i++) num[pos] += (x[left - i - 1] - '0')*(int)pow(10.0,double(i)); pos++; } } void num2str(int x, string &str){ int temp[10] = { 0 }, pos = 0; while (x){ temp[pos++] = x % 10; x /= 10; } for (int i = 7; i >= 0; i--) str += temp[i] + '0'; } void Add(string x, string & y, string &z) { string rest = ""; int num1[maxn] = { 0 }, num2[maxn] = { 0 }; int len = x.size() > y.size() ? x.size() : y.size(); str2num(x, num1); str2num(y, num2); for (int i = 0; i <= len / 8; i++){ num1[i] += num2[i]; if (num1[i] >= carry){ num1[i + 1] += num1[i] / carry; num1[i] %= carry; } } int k; for (k = len; k>0 && !num1[k]; k--); for (; k >= 0; k--) num2str(num1[k], rest); z = rest; } int cmp(string &x, string &y){ int len1 = x.size(), len2 = y.size(); int i; for (i = 0; i<len1&&!(x[i] - '0');)i++; x = x.substr(i, len1 - i + 1); // cout<<i<<endl; for (i = 0; i<len2&&!(y[i] - '0');)i++; y = y.substr(i, len2 - i + 1); // cout<<x<<" "<<y<<endl; len1 = x.size(), len2 = y.size(); if (x == y)return 0; if (len1>len2)return 1; else if (len1<len2)return -1; else if (x>y)return 1; else return -1; } string str1, str2; int calc(string &x, int left, int right, int dir) { int cmpleft = cmp(x, num[left]), cmpright = cmp(x, num[right]), mid = (left + right) / 2; if (cmpleft<0){ if (dir) return left; else return left - 1; } else if (cmpright>0){ if (!dir) return right; else return right +1; } else if (!cmpleft)return left; else if (!cmpright)return right; int cmpmid = cmp(x, num[mid]); if (!cmpmid)return mid; else if (cmpmid<0)return calc(x, left, mid - 1,dir); else return calc(x, mid + 1, right, dir); }