A - Number Sequence(矩阵快速幂或者找周期)
2015-11-05 18:32
477 查看
Description
A number sequence is defined as follows:
f(1) = 1, f(2) = 1, f(n) = (A * f(n - 1) + B * f(n - 2)) mod 7.
Given A, B, and n, you are to calculate the value of f(n).
Input
The input consists of multiple test cases. Each test case contains 3
integers A, B and n on a single line (1 <= A, B <= 1000, 1 <= n
<= 100,000,000). Three zeros signal the end of input and this test
case is not to be processed.
Output
For each test case, print the value of f(n) on a single line.
Sample Input
1 1 3
1 2 10
0 0 0
Sample Output
2 5
题目地址
A number sequence is defined as follows:
f(1) = 1, f(2) = 1, f(n) = (A * f(n - 1) + B * f(n - 2)) mod 7.
Given A, B, and n, you are to calculate the value of f(n).
Input
The input consists of multiple test cases. Each test case contains 3
integers A, B and n on a single line (1 <= A, B <= 1000, 1 <= n
<= 100,000,000). Three zeros signal the end of input and this test
case is not to be processed.
Output
For each test case, print the value of f(n) on a single line.
Sample Input
1 1 3
1 2 10
0 0 0
Sample Output
2 5
题目地址
问题:arr[1] = 1; arr[2] = 1; arr[i] = A*arr[i-2]+B*arr[i-1]; 测试案例有若干项,每个案例给出A, B, n,输出arr 的值 输入以0,0,0结束 分析:这种有规律的序列都是有周期的, 每输入一组数据,计算出一个周期内的所有的数,和周期大小 输入n之后就可以找出第n项了 因为每一项只能是 1~7 之间的数字,而后一项又与前两项有关,所以周期为A(7, 2) 分析到这里我们就可以介绍下面两种方法了 Ⅰ方法一,矩阵快速幂算类似于斐波那契数列 对于这样的数列: f(1) = a, f(2) = b, f(n) = A * f(n - 2) + B * f(n - 1). 可以用以下方法求f(n) 我们注意到从第三项开始 (可以在演草纸上算出)
从第三项开始,我们可以先算出 ,然后用结果矩阵的上边的元素作为计算的f(n) 比如 那么f(n) = a[0][0]*b + a[0][1]*a; Ⅱ 方法二: 我们已经分析了这个数列是又周期的,周期为42,因为f(1) = 1, f(2) = 1 所以,当再次遇到1, 1的时候,就已经找到所有的答案了 用一个数组存储这个数列一个周期里的结果,输出即可 方法分析:如果我们没有算出这个数列的周期,而且我们不确定这个周期到底多大,那么可以采用第一种方法, 因为这种情况如果采用第二种方法就可能出现开的存储一个周期内数据的数组太小的情况, 现在我们既然知道周期了,当然是第二种方法比较简单 但是我真心不知道为什么我用第二种方法的时候竟然和我开的数组大小有关,M = 50对,M = 10000对,还有一些数据对,但是M为其他数就不对了 我就郁闷了,和我开的数组大小有毛线关系 代码1:
#include <cstdio> #include <cstring> #define N 2 struct Mat { int arr ; }; //定义矩阵 Mat multiply(Mat x, Mat y)//矩阵乘法 { Mat res; memset(res.arr, 0, sizeof(res.arr)); for(int i = 0; i < N; i++) { for(int j = 0; j < N; j++) { for(int k = 0; k < N; k++) { res.arr[i][j] += x.arr[i][k] * y.arr[k][j]; //res.arr[i][j] %= 7; } } } return res; } Mat cacl(Mat a, int n) //矩阵快速幂,算a的n次方 { Mat res; for(int i = 0; i < N; i++) { for(int j = 0; j < N; j++) res.arr[i][j] = (i == j); } while(n) { if(n & 1) res = multiply(res, a); n /= 2; a = multiply(a, a); } return res; } int main() { int A, B, n; Mat a; while(scanf("%d%d%d", &A, &B, &n), (A || B || n)) { a.arr[0][0] = A; a.arr[0][1] = B; a.arr[1][0] = 1; a.arr[1][1] = 0; n %= 42; if(n == 1 || n == 2) printf("1\n"); else { Mat tmp = cacl(a, n-2); int ans = (tmp.arr[0][0] + tmp.arr[0][1]) % 7; printf("%d\n", ans); } } return 0; }
方法二代码:
#include <stdio.h> #define M 10000 int cacl(int arr[], int A, int B) { int i; arr[1] = arr[2] = 1; for(i = 3; i<= M-1; i++) { arr[i] = (A*arr[i-1] + B*arr[i-2]) % 7; //printf("arr[%d] = %d\n", i, arr[i]); if(arr[i] == 1 && arr[i-1] == 1) break; } arr[0] = arr[i-2]; return (i-2); } int main() { int arr[M]; int A, B, n; int T; while(scanf("%d%d%d", &A, &B, &n), (A||B||n)) { T = cacl(arr, A, B); //printf("T = %d\n", T); n %= T; printf("%d\n", arr ); } return 0; }
相关文章推荐
- UEditor图片上传
- 有关easyui打印中应用插件Lodop,非常好用
- [note]Why I haven’t quit my corporate job (yet)
- C# this.invoke()作用 多线程操作UI
- 3.30uitableview的知识点
- UIButton 如何设置为圆角矩形
- UIViewController中edgesForExtendedLayout属性的画面切断现象
- iOS开发--UIDatePicker
- UITextField (文本输入框基本设置和代理)
- 黑马程序员——JAVA基础----GUI
- IOS学习路线:IOS UI状态保持与恢复
- Qt数据库 QSqlQueryModel实例操作
- BuildConfig 中 DEBUG的作用
- [hadoop2.7.1]I/O之“泥坯块”SequenceFile前序知识
- 百度ueditor 拖文件或world 里面复制粘贴图片到编辑中 上传到第三方问题
- tornado 学习笔记8 模板以及UI
- [BZOJ 2079] Poi 2010 Guilds · 思路题
- 百度自动更新SDK的’requiresFadingEdge’错误
- EasyUi之datagird解读
- POJ-2533Longest Ordered Subsequence(LIS)