題目描述
小明的數學作業要計算方陣,現在請你幫幫他!
題目給定數個 $N \times N$ 的矩陣和 $2$ 小題。
- $X = AB+CD$
- $Y = ABE+CDF$
sequence.c
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071 #include <stdio.h>
#include <stdint.h>
// #define DEBUG
#define UINT uint32_t
#define MAXN 1024
void
multiply(
int
N,
UINT
A[][MAXN],
UINT
B[][MAXN],
UINT
C[][MAXN]) {
for
(
int
i = 0; i < N; i++) {
for
(
int
j = 0; j < N; j++) {
UINT
sum = 0;
// overflow, let it go.
for
(
int
k = 0; k < N; k++)
sum += A[i][k] * B[k][j];
C[i][j] = sum;
}
}
}
void
add(
int
N,
UINT
A[][MAXN],
UINT
B[][MAXN],
UINT
C[][MAXN]) {
for
(
int
i = 0; i < N; i++) {
for
(
int
j = 0; j < N; j++)
C[i][j] = A[i][j] + B[i][j];
}
}
void
rand_gen(
UINT
c,
int
N,
UINT
A[][MAXN]) {
UINT
x = 2, n = N*N;
for
(
int
i = 0; i < N; i++) {
for
(
int
j = 0; j < N; j++) {
x = (x * x + c + i + j)%n;
A[i][j] = x;
}
}
}
void
print_matrix(
int
N,
UINT
A[][MAXN]) {
for
(
int
i = 0; i < N; i++) {
fprintf
(stderr,
"["
);
for
(
int
j = 0; j < N; j++)
fprintf
(stderr,
" %u"
, A[i][j]);
fprintf
(stderr,
" ]\n"
);
}
}
UINT
signature(
int
N,
UINT
A[][MAXN]) {
UINT
h = 0;
for
(
int
i = 0; i < N; i++) {
for
(
int
j = 0; j < N; j++)
h = (h + A[i][j]) * 2654435761LU;
}
return
h;
}
UINT
IN[6][MAXN][MAXN], TMP[6][MAXN][MAXN];
int
main() {
int
N, S[6];
scanf
(
"%d"
, &N);
for
(
int
i = 0; i < 6; i++) {
scanf
(
"%d"
, &S[i]);
rand_gen(S[i], N, IN[i]);
}
// AB
multiply(N, IN[0], IN[1], TMP[0]);
// CD
multiply(N, IN[2], IN[3], TMP[1]);
// AB+CD
add(N, TMP[0], TMP[1], TMP[2]);
printf
(
"%u\n"
, signature(N, TMP[2]));
// ABE
multiply(N, TMP[0], IN[4], TMP[3]);
// CDF
multiply(N, TMP[1], IN[5], TMP[4]);
// ABE+CDF
add(N, TMP[3], TMP[4], TMP[5]);
printf
(
"%u\n"
, signature(N, TMP[5]));
return
0;
}
輸入格式
測資只有一組,第一行會有一個整數 $N$,表示題目給定 $N \times N$ 矩陣,第二行上會有 $6$ 個整數,分別為矩陣 $A, B, C, D, E, F$ 的生成種子。
- $1 \le N \le 1024$
- $0 \le S_i \le 2^{31}$
輸出格式
輸出兩行 $X$ 和 $Y$ 的雜湊值,可參考 sequence.c
的流程。
範例輸入 1
2
0 1 2 3 4 5
$$ A = \begin{bmatrix} 0 & 1\\ 2 & 2 \end{bmatrix}, B = \begin{bmatrix} 1 & 3\\ 3 & 0 \end{bmatrix}, C = \begin{bmatrix} 2 & 3\\ 0 & 0 \end{bmatrix}, D = \begin{bmatrix} 3 & 1\\ 1 & 2 \end{bmatrix}, E = \begin{bmatrix} 0 & 1\\ 2 & 2 \end{bmatrix}, F = \begin{bmatrix} 1 & 3\\ 3 & 0 \end{bmatrix} $$
$$ AB = \begin{bmatrix} 3 & 0\\ 8 & 6 \end{bmatrix}, CD = \begin{bmatrix} 9 & 8\\ 0 & 0 \end{bmatrix}, AB+CD = \begin{bmatrix} 12 & 8\\ 8 & 6 \end{bmatrix}\\ ABE = \begin{bmatrix} 0 & 3\\ 12 & 20 \end{bmatrix}, CDF = \begin{bmatrix} 33 & 27\\ 0 & 0 \end{bmatrix}, ABE+CDF = \begin{bmatrix} 33 & 30\\ 12 & 20 \end{bmatrix} $$
範例輸出 1
2385860290
1374821695
範例輸入 2
10
0 1 2 3 4 5
範例輸出 2
617438354
1897844131
編譯參數
$ gcc -std=c99 -O2 main.c -lm -lOpenCL -fopenmp
$ ./main
備註
- 2022/05 建議設定MAXGPU為1,第三張GPU偶爾會讓系統當機