信息学奥赛一本通题目解析:1202:Pell数列(递归函数)

【题目描述】

Pell数列a1,a2,a3,...的定义是这样的,a1=1,a2=2,...,an=2an−1+an−2(n>2)。

给出一个正整数 k,要求Pell数列的第 k项模上 3276732767 是多少。

【输入】

第1行是测试数据的组数 n,后面跟着 n行输入。每组测试数据占 11 行,包括一个正整数k(1≤k<1000000)。

【输出】

n行,每行输出对应一个输入。输出应是一个非负整数。

【输入样例】

2
1
8

【输出样例】

1
408

【解题思路】

Pell数列的定义

Pell数列是通过以下递归关系定义的:

  • a1 = 1
  • a2 = 2
  • 对于所有n > 2an = 2*an-1 + an-2

这意味着,每一项都是前一项的两倍加上前前一项。

解题思路

  1. 初始化:由于第一个和第二个数是固定的,即a1 = 1a2 = 2,我们可以从第三个数开始计算。

  2. 循环计算:使用一个循环,从3k,使用Pell数列的定义来计算每一项。由于每次计算只需要前两项,我们可以仅保留最近的两项来减少内存使用。

  3. 模运算的性质:由于最终结果需要对32767取模,我们可以利用模运算的性质((a + b) % c = ((a % c) + (b % c)) % c)在每步计算中应用模运算,以避免整数溢出并减少计算时间。

  4. 输出结果:计算出第k项后,输出其对32767取模的结果。

【实现代码】

#include <iostream>
using namespace std;

int pell(int k) {
    if (k == 1) return 1;
    if (k == 2) return 2;
    
    int a = 1, b = 2, c;
    for (int i = 3; i <= k; ++i) {
        c = (2 * b + a) % 32767; // 计算当前项并取模
        a = b; // 更新前两项
        b = c;
    }
    return c;
}

int main() {
    int n;
    cin >> n; // 读取测试数据组数
    while (n--) {
        int k;
        cin >> k; // 读取每组测试数据
        cout << pell(k) << endl; // 输出每组数据的结果
    }
    return 0;
}

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值