Problem C. Numbers
Small input 15 points |
|
Large input 35 points |
|
Problem
In this problem, you have to find the last three digits before the decimal point for the number (3 + √5)n.
For example, when n = 5, (3 + √5)5 = 3935.73982... The answer is 935.
For n = 2, (3 + √5)2 = 27.4164079... The answer is 027.
Input
The first line of input gives the number of cases, T. T test cases follow, each on a separate line. Each test case contains one positive integer n.
Output
For each input case, you should output:
Case #X: Ywhere X is the number of the test case and Y is the last three integer digits of the number (3 + √5)n. In case that number has fewer than three integer digits, add leading zeros so that your output contains exactly three digits.
Limits
1 <= T <= 100
Small dataset
2 <= n <= 30
Large dataset
2 <= n <= 2000000000
Sample
题目链接:Problem C. Numbers
挑战编程书上的题目,跟HDU的4565有点像,只是这题a与b固定,要求的是整数部分的最后三位数字,不足补0。
一开始书上的公式看不懂,问了下同学才弄懂,可以参考草稿纸上写的推出$a_n$的公式
按照这个思路可以知道题目中所求的答案就是$2*a_n-1$了
然后构造矩阵去求$a_n$即可
代码:
#include <bits/stdc++.h> using namespace std; #define INF 0x3f3f3f3f #define LC(x) (x<<1) #define RC(x) ((x<<1)+1) #define MID(x,y) ((x+y)>>1) #define CLR(arr,val) memset(arr,val,sizeof(arr)) #define FAST_IO ios::sync_with_stdio(false);cin.tie(0); typedef pair<int, int> pii; typedef long long LL; const double PI = acos(-1.0); const int N = 2; int a = 3, b = 5, n, m = 1000; int mul(int a, int b) { int r = 0; while (b) { if (b & 1) r = (r + a) % m; a = (a << 1) % m; b >>= 1; } return r; } struct Mat { int A[N][N]; void zero() { for (int i = 0; i < N; ++i) for (int j = 0; j < N; ++j) A[i][j] = 0; } void one() { for (int i = 0; i < N; ++i) for (int j = 0; j < N; ++j) A[i][j] = (i == j); } Mat operator*(Mat b) { Mat c; c.zero(); for (int k = 0; k < N; ++k) { for (int i = 0; i < N; ++i) { if (A[i][k]) { for (int j = 0; j < N; ++j) { if (b.A[k][j]) c.A[i][j] = (c.A[i][j] + mul(A[i][k], b.A[k][j])) % m; } } } } return c; } friend Mat operator^(Mat a, int b) { Mat r; r.one(); while (b) { if (b & 1) r = r * a; a = a * a; b >>= 1; } return r; } }; int main(void) { while (~scanf("%d", &n)) { Mat A, B; A.zero(); B.zero(); A.A[0][0] = 1; A.A[0][1] = 0; A.A[1][0] = 1; A.A[1][1] = 0; B.A[0][0] = a; B.A[0][1] = 1; B.A[1][0] = b; B.A[1][1] = a; A = A * (B ^ n); printf("Case #%d: %03d ", q, ((A.A[0][0] << 1) - 1) % m); } return 0; }