C. Construct a Matrix
1. The matrix is a S(n)×S(n) matrix;
2. S(n) is the sum of the first n Fibonacci numbers modulus m, that is S(n) = (F1 + F2 + … + Fn) % m;
3. The matrix contains only three kinds of integers ‘0’, ‘1’ or ‘-1’;
4. The sum of each row and each column in the matrix are all different.
Here, the Fibonacci numbers are the numbers in the following sequence: 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, …
By definition, the first two Fibonacci numbers are 1 and 1, and each remaining number is the sum of the previous two.
In mathematical terms, the sequence Fn of Fibonacci numbers is defined by the recurrence relation Fn = Fn-1 + Fn-2, with seed values F1 = F2 = 1.
Given two integers n and m, your task is to construct the matrix.
Input
Output
Sample Input
2 2 3 5 2
Sample Output
Case 1: Yes -1 1 0 1 Case 2: No
题意:求fib数列前n项和,以这个和%m作为矩阵的r,然后构造矩阵满足所有值为0,1 或 -1,并且每行每列和都不相等。
思路:第一步矩阵快速幂,第二步找规律。
代码:
#include <stdio.h> #include <string.h> const int N = 205; int t, n, m, r; struct mat { int v[3][3]; mat() { memset(v, 0, sizeof(v)); } mat operator * (mat &b) { mat c; for (int i = 0; i < 3; i ++) for (int j = 0; j < 3; j ++) for (int k = 0; k < 3; k ++) c.v[i][j] = (v[i][k] * b.v[k][j] + c.v[i][j]) % m; return c; } }; mat pow_mod(mat a, int k) { if (k == 1 || k == 0) return a; mat c = pow_mod(a * a, k / 2); if (k & 1) c = c * a; return c; } void init() { scanf("%d%d", &n, &m); mat start; start.v[0][0] = start.v[0][1] = start.v[1][0] = start.v[2][0] = start.v[2][1] = start.v[2][2] = 1; if (n == 1) r = 1; else if (n == 2) r = 2; else { mat end = pow_mod(start, n - 2); r = (end.v[2][0] + end.v[2][1] + end.v[2][2] * 2) % m; } } void solve() { int s[N][N]; memset(s, -1, sizeof(s)); if (r == 0 || r % 2) printf("No "); else { printf("Yes "); for (int i = 1; i <= r; i++) { if (i % 2) { int tmp = r / 2 + (i + 1) / 2; s[tmp][i] = 0; for (int j = tmp + 1; j <= r; j++) s[j][i] = 1; } else { int tmp = (r - i) / 2; for (int j = tmp + 1; j <= r; j++) s[j][i] = 1; } } for (int i = 1; i <= r; i++) { // int sum = 0; for (int j = 1; j < r; j++) { printf("%d ", s[i][j]); // sum += s[i][j]; } printf("%d ", s[i][r]); } /* for (int j = 1; j <= r; j++) { int sum = 0; for (int i = 1; i <= r; i++) sum += s[i][j]; printf("%d ", sum); } printf(" "); */ } } int main() { int cas = 0; scanf("%d", &t); while (t --) { init(); printf("Case %d: ", ++cas); solve(); } return 0; }