Medium · 2D loops
Matrix Multiplication
Every output cell is a dot product: row i of A walks arm-in-arm with column j of B, and the middle dimension m is the only thing they share. Get the three roles straight — A is n×m, B is m×k, C is n×k — and the code writes itself.
At a glance<code>C[i][j] = sum over t of A[i][t] * B[t][j]</code> — three loops, C zeroed cell by cell, dimensions n×m, m×k → n×k.
Problem
Input: The first line has n, m, k (1 ≤ each ≤ 10). Then n lines of m integers: matrix A. Then m lines of k integers: matrix B. Values from −100 to 100.
Output: n lines of k integers: the product A×B, values separated by single spaces.
Samples:
| Input | Output |
|---|---|
2 2 2 | 19 22 |
1 1 1 | 12 |
Check the first cell by hand: C[1][1] = 1·5 + 2·7 = 19. Row meets column, multiply pairwise, add — if you can do one cell, the loops just do all of them.
Your solution
Custom input for "Run my input"
Judging runs in your browser against hidden tests. A runaway loop is cut off after 3 seconds — still, make sure every loop has an exit. Your code is saved in this browser as you type.
Stuck? Hints
Hint 1 — Zero each cell yourself
C is a global array, and on this site's engine global arrays are not automatically zeroed (real C++ zeroes them; our interpreter does not). The safe habit anyway: C[i][j] = 0; as the first line inside the i/j loops, then accumulate with +=. Explicit beats implicit whenever memory is involved.
Hint 2 — The middle index is the hinge
The summation index t runs over m — A's columns and B's rows. A common swap of roles writes A[t][i] or B[j][t]; both compile fine and both are wrong. Say the shape out loud once: A is n by m, B is m by k — the shared m is why the multiplication is even defined.
Hint 3 — Print with the same discipline as the judge
Rows are space-separated, rows end with a newline, no trailing space after the last number of a row: print the separator before every value except the first, exactly as you did in Bubble Sort. Output formatting is part of the problem statement, not a detail.
Solution (try it first!)
#include <iostream>
using namespace std;
int A[12][12], B[12][12], C[12][12];
int main() {
int n, m, k;
cin >> n >> m >> k;
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++)
cin >> A[i][j];
for (int i = 0; i < m; i++)
for (int j = 0; j < k; j++)
cin >> B[i][j];
for (int i = 0; i < n; i++) {
for (int j = 0; j < k; j++) {
C[i][j] = 0;
for (int t = 0; t < m; t++) {
C[i][j] += A[i][t] * B[t][j];
}
}
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < k; j++) {
cout << C[i][j];
if (j < k - 1) cout << " ";
}
cout << endl;
}
return 0;
}
The triple loop you just wrote is, verbatim, what BLAS libraries optimize into gigaflops — the mathematics never changes, only the memory layout does. You have now handled the full 2D trio: summing (Sum a Matrix), reindexing (Matrix Transpose), and combining (this one). What is left in grid land is asking questions about rectangles — 2D Range Sums.
Deep dive
Why this works
Each output cell is a dot product: row i of A against column j of B, summed over the shared dimension m. The triple loop is the definition read aloud — n×k cells, each summing m products. There is nothing to prove; the difficulty is purely keeping three dimensions in their lanes.
The cost
O(n·m·k) — 10×10×10 = 1,000 multiply-adds here. The same loop at 1000×1000 is a billion operations, which is why libraries (BLAS) exist: same math, rearranged memory.
Where it goes wrong
- Swapping roles in the inner product:
A[t][i]orB[j][t]compile fine and are wrong. The hinge isA[i][t] * B[t][j]— row of A, column of B. - Trusting zero-initialized globals: on this engine global arrays are not zeroed, so
C[i][j] = 0;inside the loop is mandatory, not stylistic. - Output discipline: separator before every value except the first of each row, newline after — the judge compares characters, not intentions.
Next step
You now hold the whole 2D trio: summing (Sum a Matrix), reindexing (Matrix Transpose), combining (this). The next grid skill asks questions about rectangles: 2D Range Sums.
Two things to remember
- C[i][j] = Σ A[i][t]·B[t][j] — the shared m is why it is defined.
- Zero accumulator cells explicitly; never trust a global array to start clean.
🐞 This version fails — open it and try
Inner loop runs to k instead of m — only square tests would forgive it
#include <iostream>
using namespace std;
int A[12][12], B[12][12], C[12][12];
int main() {
int n, m, k;
cin >> n >> m >> k;
for (int i = 0; i < n; i++) for (int j = 0; j < m; j++) cin >> A[i][j];
for (int i = 0; i < m; i++) for (int j = 0; j < k; j++) cin >> B[i][j];
for (int i = 0; i < n; i++) {
for (int j = 0; j < k; j++) {
C[i][j] = 0;
for (int t = 0; t < k; t++) { // bug: k instead of m
C[i][j] += A[i][t] * B[t][j];
}
}
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < k; j++) {
cout << C[i][j];
if (j < k - 1) cout << " ";
}
cout << endl;
}
return 0;
}