計算兩個 n×n (n ≤ 800) 矩陣乘積對 3 取模的結果。普通 O(n³) 會超時,需極致優化。
k 迴圈提到最外層,改為 i → k → j。這樣 B[k][j] 連續訪問,A[i][k] 在內層迴圈不變,極大減少緩存未命中。ReadInt() 直接讀字符並對 3 取模,避免 scanf 開銷。A[i][k] == 0 則跳過內層 j 迴圈,因為乘 0 無貢獻。void Solve() {
memset(mtRet, 0, sizeof(mtRet));
for (int i = 1; i <= n; ++i) {
for (int k = 1; k <= n; ++k) {
if (!A[i][k]) continue; // 剪枝
for (int j = 1; j <= n; ++j) {
mtRet[i][j] += A[i][k] * B[k][j];
}
}
}
}
int ReadInt() {
int ret = 0; char c;
while ((c = getchar()) >= '0' && c <= '9')
ret = ret * 10 + c - '0';
return ret % 3; // 讀入即取模
}
注意:本題利用模 3 特性(數值極小)與 n=800 邊界,使 O(n³) 通過。一般矩陣乘法需 Strassen 或分塊算法。