HDU1799——循环多少次?,HDU1316——多少斐波那契?,HDU1715——大菲波数

38 篇文章 0 订阅

HDU1799——循环多少次?

题目描述

问题 - 1799 (hdu.edu.cn)

运行代码

#include <iostream>
using namespace std;
const int N = 2005;
int db[N][N];
void dabiao() {
    for (int i = 1; i <= 2000; ++i) {
        db[1][i] = 0;
        db[i][1] = i % 1007;
    }
    for (int i = 2; i <= 2000; ++i) {
        for (int j = 2; j <= i; ++j) {
            db[i][j] = (db[i - 1][j] + db[i - 1][j - 1]) % 1007;
        }
    }
}
int main() {
    dabiao();
    int t;
    cin >> t;
    while (t--) {
        int m, n;
        cin >> m >> n;
        cout << db[n][m] <<endl;
    }
    return 0;
}

代码思路

一、整体思路

  1. 定义一个二维数组 db 用来存储特定的计算结果。
  2. 通过函数 dabiao 预先计算并填充二维数组 db 的值。
  3. 读取输入的测试用例数量 t,对于每个测试用例,读取两个整数 m 和 n,并输出 db[n][m] 的值。

二、函数分析

  1. dabiao 函数

    • 这个函数的目的是通过两层循环来初始化和填充二维数组 db
    • 第一层循环 for (int i = 1; i <= 2000; ++i) 遍历数组的行。当 i = 1 时,将 db[1][i] 设置为 0,这是初始化第一行的值。当 i > 1 时,将 db[i][1] 设置为 i % 1007,这是初始化第一列的值。
    • 第二层循环 for (int i = 2; i <= 2000; ++i) 和 for (int j = 2; j <= i; ++j) 用于计算并填充除第一行和第一列之外的其他位置的值。db[i][j] = (db[i - 1][j] + db[i - 1][j - 1]) % 1007 这个公式是根据前一行的对应位置的值来计算当前位置的值,然后对 1007 取模以确保结果在特定范围内。
  2. main 函数

    • 首先调用 dabiao 函数来预先计算二维数组的值。
    • 然后读取输入的测试用例数量 t
    • 在循环中,对于每个测试用例,读取两个整数 m 和 n,并输出 db[n][m] 的值,这个值是在 dabiao 函数中预先计算好的。

HDU1316——多少斐波那契?

题目描述

问题 - 1316 (hdu.edu.cn)

运行代码

#include <iostream>
#include <vector>
#include <string>

using namespace std;

// 高精度加法
string addStrings(const string& num1, const string& num2) {
    string result;
    int carry = 0;
    int i = num1.length() - 1;
    int j = num2.length() - 1;
    while (i >= 0 || j >= 0 || carry > 0) {
        int sum = carry;
        if (i >= 0) sum += num1[i--] - '0';
        if (j >= 0) sum += num2[j--] - '0';
        carry = sum / 10;
        result += to_string(sum % 10);
    }
    reverse(result.begin(), result.end());
    return result;
}

// 比较两个高精度数字字符串
int compareStrings(const string& s1, const string& s2) {
    if (s1.length() < s2.length()) return -1;
    if (s1.length() > s2.length()) return 1;
    for (size_t i = 0; i < s1.length(); ++i) {
        if (s1[i] < s2[i]) return -1;
        if (s1[i] > s2[i]) return 1;
    }
    return 0;
}

// 二分查找下界
int findLowerBound(const vector<string>& fibonacciNumbers, const string& target) {
    int low = 0;
    int high = fibonacciNumbers.size() - 1;
    while (low <= high) {
        int mid = low + (high - low) / 2;
        int cmp = compareStrings(fibonacciNumbers[mid], target);
        if (cmp >= 0) high = mid - 1;
        else low = mid + 1;
    }
    return high;
}

// 二分查找上界
int findUpperBound(const vector<string>& fibonacciNumbers, const string& target) {
    int low = 0;
    int high = fibonacciNumbers.size() - 1;
    while (low <= high) {
        int mid = low + (high - low) / 2;
        int cmp = compareStrings(fibonacciNumbers[mid], target);
        if (cmp > 0) high = mid - 1;
        else low = mid + 1;
    }
    return low;
}

int main() {
    vector<string> fibonacciNumbers;
    fibonacciNumbers.push_back("1");
    fibonacciNumbers.push_back("2");
    string prev1 = "1";
    string prev2 = "2";
    string current;
    while (true) {
        current = addStrings(prev1, prev2);
        fibonacciNumbers.push_back(current);
        if (current.length() > 100) break;
        prev1 = prev2;
        prev2 = current;
    }

    string a, b;
    while (cin >> a >> b) {
        if (a == "0" && b == "0") break;
        int lower = findLowerBound(fibonacciNumbers, a);
        int upper = findUpperBound(fibonacciNumbers, b);
        cout << upper - lower - 1 << endl;
    }
    return 0;
}

代码思路

整体思路

  1. 首先定义了一些函数来进行高精度加法、比较两个高精度数字字符串以及使用二分查找在生成的斐波那契数列中查找特定数字的上下界。
  2. main函数中,生成一定范围内的斐波那契数列并存储在vector<string>中。
  3. 从输入读取两个数字范围ab,通过查找斐波那契数列中对应于ab的上下界,计算出在该范围内的斐波那契数的数量并输出。

二、函数分析

  1. addStrings函数

    • 这个函数实现了高精度加法。它从两个字符串表示的数字的末尾开始逐位相加,同时处理进位。
    • 通过循环,只要有数字未处理完或者有进位,就继续相加。
    • 最后将结果字符串反转后返回,确保高位在左侧。
  2. compareStrings函数

    • 用于比较两个高精度数字字符串的大小。
    • 首先比较字符串长度,如果长度不同,长度长的数字较大。
    • 如果长度相同,则逐位比较字符,一旦发现不同的字符,就根据其大小关系返回结果。如果所有字符都相同,则返回相等。
  3. findLowerBoundfindUpperBound函数

    • 这两个函数都是使用二分查找在给定的斐波那契数列中查找特定数字的上下界。
    • 在二分查找过程中,通过比较中间元素与目标数字的大小关系来调整查找区间。
    • 如果中间元素大于等于目标数字,则在左半区间继续查找(下界)或调整上界(上界);如果中间元素小于目标数字,则在右半区间继续查找(下界)或调整下界(上界)。

三、主程序流程

  1. 生成斐波那契数列:从初始的两个斐波那契数 “1” 和 “2” 开始,通过不断调用addStrings函数生成后续的斐波那契数,直到生成的数字长度超过 100 为止,并将这些数字存储在vector<string>中。

  2. 处理输入:从标准输入读取两个字符串ab,代表数字范围。如果ab都为 “0”,则结束程序。对于每个输入的范围,将字符串ab进行处理,使得高位在左侧,低位在右侧,方便后续的比较和计算。

  3. 计算范围内的斐波那契数数量:使用findLowerBound函数找到大于等于a的第一个斐波那契数的下标,记为lower。使用findUpperBound函数找到大于b的第一个斐波那契数的下标,记为upper。范围内的斐波那契数数量为upper - lower - 1,并输出这个结果。

HDU1715——大菲波数

题目描述

Problem - 1715 (hdu.edu.cn)

运行代码

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

vector<int> add(const vector<int>& a, const vector<int>& b) {
    vector<int> result;
    int carry = 0;
    int i = 0;
    while (i < a.size() || i < b.size() || carry > 0) {
        int sum = carry;
        if (i < a.size()) sum += a[i];
        if (i < b.size()) sum += b[i];
        result.push_back(sum % 10);
        carry = sum / 10;
        i++;
    }
    return result;
}

vector<int> fibonacci(int n) {
    if (n == 1 || n == 2) {
        return {1};
    }
    vector<int> a = {1};
    vector<int> b = {1};
    vector<int> c;
    for (int i = 3; i <= n; i++) {
        c = add(a, b);
        a = b;
        b = c;
    }
    return b;
}

int main() {
    int N;
    cin >> N;
    for (int i = 0; i < N; i++) {
        int p;
        cin >> p;
        vector<int> result = fibonacci(p);
        for (int j = result.size() - 1; j >= 0; j--) {
            cout << result[j];
        }
        cout << endl;
    }
    return 0;
}

代码思路

一、整体思路

  1. 定义了两个主要函数:add用于高精度整数加法,fibonacci用于计算斐波那契数列的第n项。
  2. main函数中,首先读取输入的测试用例数量N,然后对于每个测试用例(整数p),调用fibonacci函数计算并输出第p个斐波那契数。

二、函数分析

  1. add函数

    • 目的是将两个高精度整数相加。
    • 初始化结果向量result和进位carry为 0。
    • 通过循环,遍历两个输入向量ab,同时考虑进位情况。
    • 对于每一位,计算当前位的和(包括上一位的进位),取和的个位作为当前位结果存入result,并更新进位为和除以 10 的商。
    • 循环结束后,如果进位不为 0,将进位也加入结果向量。
  2. fibonacci函数

    • 如果输入的n为 1 或 2,直接返回只有一个元素 1 的向量,表示第 1 和第 2 个斐波那契数。
    • 对于n大于 2 的情况,使用迭代的方法计算斐波那契数。
    • 初始化两个向量ab分别为第 1 和第 2 个斐波那契数。
    • 通过循环从第 3 项开始计算,每次将ab相加得到新的斐波那契数向量c,然后更新abbc。循环结束后,b存储的就是第n个斐波那契数。

三、主程序流程

  1. 读取输入的测试用例数量N
  2. 对于每个测试用例:读取整数p。调用fibonacci(p)计算第p个斐波那契数,得到一个高精度整数向量。从向量的最后一位开始输出,依次输出每一位数字,得到第p个斐波那契数的结果。

  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

筱姌

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值