清华大学2009年机试-递推数列-1081
题目描述:
给定a0,a1,以及an=p*a(n-1) + q*a(n-2)中的p,q。这里n >= 2。 求第k个数对10000的模。
输入
输入包括5个整数:a0、a1、p、q、k。
输出
第k个数a(k)对10000的模。
样例输入
20 1 1 14 5
样例输出
8359
解题思路:
首先,第一反应是用递归解题,然而时间复杂度过大。接着尝试了用数组存储结果,在牛客网的平台上能通过测试,但是数组开的不够大,在九度的案例上会出现RUNTIME ERROR(应该是这个原因吧)。在网上查询资料之后,发现大家解决这类问题用的一般是矩阵乘法(配上快速幂,也叫矩阵二分乘法),看来我的基础还是不够好啊。。。
普通思路:
#include <cstdio>
#define MAXN 1000000
int a0, a1, p, q, k;
const int mod = 10000;
int a[MAXN];
void init(int k){
a[0] = a0;
a[1] = a1;
for(int i = 2; i <= k; i++){
a[i] = (p*a[i-1]%mod + q*a[i-2]%mod)%mod;
}
}
int main(){
while(scanf("%d%d%d%d%d", &a0, &a1, &p, &q, &k) != EOF){
init(k);
printf("%d\n", a[k]);
}
return 0;
}
矩阵乘法思路:
#include <cstdio>
#define MAXN 1000000
int a0, a1, p, q, k;
const int mod = 10000;
struct matrix{
int m00, m01, m10, m11;
};
void matrixMul(matrix *m1, matrix *m2){
matrix tmp;
tmp.m00 = (m1->m00*m2->m00 + m1->m01*m2->m10) % mod;
tmp.m01 = (m1->m00*m2->m01 + m1->m01*m2->m11) % mod;
tmp.m10 = (m1->m10*m2->m00 + m1->m11*m2->m10) % mod;
tmp.m11 = (m1->m10*m2->m01 + m1->m11*m2->m11) % mod;
*m1 = tmp;
}
int main(){
while(scanf("%d%d%d%d%d", &a0, &a1, &p, &q, &k) != EOF){
if (k == 0) {
printf ("%d\n", a0 % mod);
continue;
}
if (k == 1) {
printf ("%d\n", a1 % mod);
continue;
}
matrix m = {1, 0, 0, 1}, base = {p%mod, q%mod, 1, 0};
int num = k-1;
while(num != 0){
if(num&1) matrixMul(&m, &base);
matrixMul(&base, &base);
num >>= 1;
}
printf("%d\n", (m.m00*a1 + m.m01*a0)%mod);
}
return 0;
}