C++ zoj1962 How Many Fibs?

C++ zoj1962 How Many Fibs?_第1张图片一、题目大意:

      有多组测试数据,每组测试数据占一行,每行给出a和b两个非负整数(a <= b <= 10^100),问a和b之间存在多少个Fibonacci数

 

二、思路:

(1)先生成498个Fibonacci数,存到二维数组fb[i]中。因为第498个Fibonacci数是104位,题目要求是100位范围内的,所以开辟的空间i(i存储第i+1个Fibonacci数)为500就行了,j(存储第i个Fibonacci数的第j+1数位)最大存储位数是100,所以用105个空间存储。

(2)找到比数a刚好相等或者大于的Fibonacci数,返回是第几个Fibonacci数,num1;

(3)找到比数b刚好相等或者大于的Fibonacci数,返回是第几个Fibonacci数,num2;

(4)将num2-num1就得到a和b之间有多少个Fibonacci数

 

三、实现程序

#include 
#include 
using namespace std;

const int MAXX = 500;
const int MAXY = 105;

int Compare1(int a[], int fb[][MAXY], int lenFb[], int len1) {
    // 遍历498个已生成的Fibonacci数,找到刚好大于或者等于a的Fibonacci数是第几个
    for (int i = 0; i < 498; i++) {
        // 如果长度小于a数的长度,说明比a小,直接跳过
        if (lenFb[i] < len1)
            continue;
        else if (lenFb[i] == len1) { // 如果当前的Fibonacci数和a长度(位数)相等
            int j;
            // 位数相等,则从高位往低位逐个数位进行比较
            for (j = len1 - 1; j >= 0; j--) {
                if (fb[i][j] < a[j]) // 如果小,说明当前Fibonacci数较小,则直接跳过
                    break;
                // 如果大,则说明当前Fibonacci数大,返回是第几个Fibonacci数
                else if (fb[i][j] > a[j])
                    return i;
            }
            if (j == -1) // 说明当前Fibonacci数是和a相等的,返回是第几个Fibonacci数
                return i;
        }
        else // 如果位数相等的情况下,a还是比Fibonacci数大,则找位数比a多的Fibonacci数
            return i;
    }
    return 0;
}

// 遍历498个已生成的Fibonacci数,找到刚好大于或者等于b的Fibonacci数,是第几个
int Compare2(int b[], int fb[][MAXY], int lenFb[], int len2, int l) {
    for (int i = 0; i < 498; i++) {
        if (lenFb[i] < len2) // 长度小的直接跳过
            continue;
        else if (lenFb[i] == len2) {
            int j;
            for (j = len2 - 1; j >= 0; j--) {
                if (fb[i][j] < b[j]) // 小于
                    break;
                else if (fb[i][j] > b[j]) // 大于
                    return i;
            }
            if (j == -1) // 相等
                return (i + 1);
        }
        else // 刚好位数多一位的Fibonacci数,又刚好大于b
            return i;
    }
    return 0;
}

int main()
{
    char str1[MAXY], str2[MAXY];
    int a[MAXY], b[MAXY];
    
    while (cin >> str1 >> str2) { // 输入两个数a和b的字符串
        int len1, len2;
        
        // 如果a和b同时为0,结束程序
        if (str1[0] == '0' && str2[0] == '0')
            break;
        len1 = strlen(str1); // 取字符串的长度
        len2 = strlen(str2);
        
        // 1.逆转字符串,存到整型数组a和b中
        for (int i = 0; i < len1; i++)
            a[len1 - i - 1] = str1[i] - '0';
        for (int i = 0; i < len2; i++)
            b[len2 - i - 1] = str2[i] - '0';
        
        // 2.计算498个Fibonacci数,并存到fb[i]数组中
        int fb[MAXX][MAXY], lenFb[MAXX], maxLen;
        memset(fb, 0, sizeof(fb)); // 将fb数组置零
        fb[0][0] = 1; // 题目中Fibonacci数的第一项
        fb[1][0] = 2; // 题目中Fibonacci数的第二项
        // maxLen存储Fibonacci数的位数,初始位数为1
        // 第i个Fibonacci数存到fb[i]中,fb[i][j]存储第i个Fibonacci数的第j位
        maxLen = lenFb[1] = lenFb[0] = 1;
        // 第498个斐波那契数是104位,而题目要求z是100位范围内,所以要求出498个Fibonacci数
        for (int i = 2; i < 498; i++) {
            for (int j = 0; j < maxLen; j++) {
                // 应用公式fn := fn-1 + fn-2 (n >= 3)
                // 将对应数位相加(fb[i - 1][j] + fb[i - 2][j]),并加上进位fb[i][j]
                fb[i][j] = fb[i][j] + fb[i - 1][j] + fb[i - 2][j];
                // 如果有进位
                if (fb[i][j] > 9) {
                    fb[i][j + 1] += 1;
                    fb[i][j] %= 10;
                }
            }
            // 如果最高位有进位,位数要加1
            if (fb[i][maxLen] > 0)
                maxLen++;
            // lenFb[i]保存对应的第i个Fibonacci数的位数
            lenFb[i] = maxLen;
        }
        
        // 3.找到数a在Fibonacci数中是第几个数
        int num1 = Compare1(a, fb, lenFb, len1);
        // 4.同理,找到数b在Fibonacci数中是第几个数
        int num2 = Compare2(b, fb, lenFb, len2, num1);
        cout << (num2 - num1) << endl;
    }
    return 0;
}

运行结果:

C++ zoj1962 How Many Fibs?_第2张图片

你可能感兴趣的:(ACM,zoj1962,How,Many,Fibs?)