PKU 3213 PM 3
問題
行列A, B, Cが与えられる。
A x B = Cになっているかどうかを検算せよ。
なっている場合はYes, そうでない場合はNoと、
Cの間違っている成分の行、列およびその成分の正しい値を出力せよ。
Cの成分は高々一つしか間違っていない。
制約条件
Aの行数, Aの列数≦1000
Bの行数, Bの列数≦1000
Cの行数, Cの列数≦1000
方針
ランダムな列ベクトルxを取って、
A(Bx) = Cxが成り立っているかを見れば、O(N^2)時間で行列積の検算ができる。
ソースコード
int A[1000][1000], B[1000][1000], C[1000][1000]; ll x[1000], xc[1000], xa[1000], xb[1000]; int n, p, m; int main(){ scanf("%d%d%d", &n, &p, &m); rep(i, n) rep(j, p) scanf("%d", A[i] + j); rep(i, p) rep(j, m) scanf("%d", B[i] + j); rep(i, n) rep(j, m) scanf("%d", C[i] + j); rep(i, m) x[i] = rand(); rep(i, n) rep(j, m) xc[i] += C[i][j] * x[j]; rep(i, p) rep(j, m) xb[i] += B[i][j] * x[j]; rep(i, n) rep(j, p) xa[i] += A[i][j] * xb[j]; rep(i, n) if(xa[i] != xc[i]){ rep(c, m){ ll a = 0; rep(r, p) a += A[i][r] * B[r][c]; if(a != C[i][c]){ cout << "No" << endl; cout << i + 1 << " " << c + 1 << endl; cout << a << endl; } } goto END; } cout << "Yes" << endl; END:; return 0; }