POJ2413 How many Fibs(高精度)(AC)

来源:互联网 发布:淘宝外卖和口碑的区别 编辑:程序博客网 时间:2024/06/04 23:21
How many Fibs?
Time Limit: 1000MS Memory Limit: 65536KTotal Submissions: 11896 Accepted: 4312

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 1001234567890 98765432100 0

Sample Output

54
//这道题的意思就是在a和b之间有多少个fib函数就可以到了
//10 100找到10位到100位之间的fib数//这么大的输入输出肯定要用数组了#define _CRT_SECURE_NO_WARNINGS#include <stdio.h>#include <string>  #define MAXN 150#define MAXF 1000int first[MAXN];int second[MAXN];int firstweishu  = 0;int secondweishu = 0;int ans = 0;int fibnum[MAXF][MAXN]; //存所有的fib数int weishu[MAXF];  //存每个fib数占的位数//#define max(a,b) (a) >=(b)?(a):(b)//WA了无数次,最后还是自己的find函数写的有问题, 因为需要考虑90 120这种情况,90不是fib数,120也不是,中间也没有fib数,因此90在找比它大的fib数的时候是找不到的//因为在比较位数比它大的数,就应该设置findflag =1,然后比较和end的数,这个改了就可以了//另外case也考虑了0982 9999这样的情况,但是应该是不会出现的//FIb数生成还是没问题的//find的思路是1 2, start是1,end是2,那就是要找到在1和2之间的数,start找到>=1的序列, end<=2的序列, start如果找到比它大的数,那还要check下这个数是否比end大//如果比end大那说明这个区间肯定没有fib数//end要找的是比它小的数,因此从最后一个和它同长度的比较起,如果位数比它短,那可以直接返回了,因为start有比较是否比end大,因为end这边不需要再比较了//最终ACint max(int a,int b){if (a >= b){return a;}else{return b;}}int index = 3;char a[MAXN] = { '\0' };char  b[MAXN] = { '\0' };void init(){int i = 0;int j = 0;for (i = 0; i < MAXN;i++){first[i] = 0;second[i] = 0;}ans = 0;return;}void initmatrix(){int i = 0;int j = 0;for (i = 0; i < MAXN; i++){a[i] = '\0';b[i] = '\0';}return;}void initfib(){int i = 0;int j = 0;for (i = 0; i < MAXF; i++){weishu[i] = 0;for (j = 0; j < MAXN; j++){fibnum[i][j] = 0;}}return;}int fib(int a){return fib(a-1) + fib(a-2);}int strlength(char* s){int size = 0;int findshuzi = 0;while ('\0' != *s){size += 1;s += 1;}return size;}int strlengths(char* s){int size = 0;int findshuzi = 0;while ('\0' != *s){if (('0' == *s) && (0 == findshuzi)){}else{size += 1;findshuzi = 1;}s += 1;}if (0 == size) size += 1;//防止0的情况return size;}void parse(){int i = 0;int j = 0;firstweishu  = strlength(a);secondweishu = strlength(b);i = firstweishu - 1;j = 0;while ('\0' != a[j]){first[i] = a[j] - '0';i -= 1;j += 1;}i = secondweishu - 1;j = 0;while ('\0' != b[j]){second[i] = b[j] - '0';i -= 1;j += 1;}firstweishu = strlengths(a);secondweishu = strlengths(b);return;}//获取105位以内的所有fib数void getfib(){int c = 0;int jinwei = 0;int i = 0;int d = 0;index = 3;fibnum[1][0] = 1;fibnum[2][0] = 2;weishu[1] = 1;weishu[2] = 1;while (1){c = max(weishu[index-2],weishu[index-1]);jinwei = 0;if (7 == index){index = index;}//从低位开始加,有进位就要记住for (i = 0; i < c;i++){d = fibnum[index-2][i] + fibnum[index-1][i] + jinwei;jinwei = 0;if (d <= 9){fibnum[index][i] = d;}else{fibnum[index][i] = d - 10;jinwei = 1; }}weishu[index] = c;//最后加过来,看是否有进位if (jinwei>0){fibnum[index][c] = jinwei;weishu[index] = c+1;}if (index>= 500) break;index += 1;}return;}int x = 0;/* 假设 存在的数 x   考察的区间为[a , b]需要注意的 又这么几种情况   a < b < x   a < b = x   a = b < x    a = b = x    x = a < b    x < a = b   x < a < b*/int findnew(int s[], int n){int k;for (int i = 0; i <= 498; i++){if (weishu[i] < n)continue;if (weishu[i] == n){int flag = 0;for (k = n - 1; k >= 0; k--){if (fibnum[i][k] > s[k])return i;elseif (fibnum[i][k] == s[k])continue;else{flag = 1;break;}}if (flag == 0){x++;return i;}}if (weishu[i] > n)return i;}return 0;}int find(int type) //1-分析第一个数,2-分析第2个数{int num = 0;int i = 0;int startindex = 0;int findflag = 0;int j = 0;int cmpindex = 0;int sameindex = 0;if (1 == type){num = firstweishu;}else{num = secondweishu;}//查找位数从哪个开始for (i = 1; i < index;i++){if (1 == type){if (num == weishu[i]){startindex = i; //找到了,然后下面开始找indexbreak;}}else{if ((num+1) == weishu[i]) //要多一位{startindex = i-1; //找到了,然后下面开始找indexbreak;}}}//start要找个比>=start的if (1 == type){while (1){findflag = 0;if (firstweishu < weishu[startindex]){findflag = 1;}else{//从startindex开始找起,从最高位开始比较for (i = num - 1; i >= 0; i--){if (fibnum[startindex][i] > first[i]){findflag = 1;  //找到大数break;}else if (fibnum[startindex][i] == first[i]) //数字相同,那要继续比较{if (i == 0){findflag = 1;}else{continue;}}else{//比现在的数小,那就只能breakbreak;}}}if (1 == findflag){cmpindex = max(secondweishu, weishu[startindex]);//check找到的数是否<endfor (j = cmpindex-1; j >= 0;j--){if (fibnum[startindex][j] < second[j] ){return startindex; }}//判断是否==endsameindex = 0;for (j = cmpindex - 1; j >= 0; j--){if (fibnum[startindex][j] == second[j]){sameindex +=1; }}if (cmpindex == sameindex) //==end{return startindex;}return 0;}else{startindex += 1;}}}else{//end要找个<=end的while (1){findflag = 0;//从startindex开始找起,从最高位开始比较if (secondweishu > weishu[startindex]){return startindex;}for (i = num - 1; i >= 0; i--){if (fibnum[startindex][i] < second[i]){findflag = 1;  //找到大数break;}else if (fibnum[startindex][i] == second[i]) //数字相同,那要继续比较{if (i == 0){findflag = 1;}else{continue;}}else{//比现在的数大,那就只能breakbreak;}}if (1 == findflag){return startindex;}else{startindex -= 1;}}}}int main(){freopen("input.txt","r",stdin);int index1 = 0;int index2 = 0;int nn = 0;int bb = 0;int i = 0;int l = 0;int k = 0;//一共有105位最大,那就求出在105位范围内的fib数initfib();getfib();while ((scanf("%s %s", a, b) != EOF && (a[0] != '0' || b[0] != '0'))){//init();parse(); //分解输入输出//分析输入的长度,上面parse函数已经得到长度了//然后从位数开始找起index1 = find(1);if (0 != index1){index2 = find(2);}if (0 != index1){ans = index2 - index1 + 1;}else{ans = 0;}if (0 == ans){ans = ans;}printf("%d\n",ans);//下面注释的是第2种做法可以AC/*firstweishu = strlengths(a);secondweishu = strlengths(b);x = 0;index1 = findnew(first, firstweishu);nn = x;x = 0;index2 = findnew(second, secondweishu);bb = x;if (nn == 1 && bb == 1){printf("%d\n", index2 - index1 + 1);continue;}else if (nn == 1 && bb == 0)printf("%d\n", index2 - index1 );elseif (nn == 0 && bb == 1)printf("%d\n", index2 - index1 + 1);elseprintf("%d\n", index2 - index1);*///initmatrix();}return 0;}


原创粉丝点击