I'm working on a HackerRank problem that's finding the largest sum of the elements in upper-left quadrant of a 2N x 2N matrix after reversing rows and columns. For example, if the matrix is
M = [
112 42 83 119
56 125 56 49
15 78 101 43
62 98 114 108
];
then the largest sum that can be formed from reversing rows and columns is 119 + 114 + 56 + 125 = 414
after getting the matrix
M' = [
119 114 42 112
56 125 101 49
15 78 56 43
62 98 83 108
];
from reversing column 2 and then row 0.
I have not figured out an easy solution, but I have come up with some facts that might be helpful:
NxN
of them. M[0,1]=42
can be replaced by M[0,2]=83
or M[3,2]=114
or M[3,1]=98
) because you have to also consider the other elements that get dragged along in the process. Other than those facts, I cannot think of anything that helps me construct a simple solution. Is there any obvious fact that I am missing? I stayed up past midnight thinking about this last night. :)
Let's develop your observation about the fact that an element (N - 1, N - 1)
can be only in (0, 0)
, (N - 1, 0)
or (0, N - 1)
position.
Consider an (r, c)
element. One can observe that it can only be in one of the following four positions: (r, c), (N - r - 1, c), (r, N - c - 1)
or (N - 1 - r, N - 1 - c)
One can show that there is always a sequence of operations that places the largest of the four numbers located in the vertices of the rectangle described above to the upper-left quadrant without changing the rest of it (to prove it, one can just consider all cases and provide an explicit construction to do it. It's quite long but straightforward, so I'll not post it here).
These two observation give the following solution:
int sum = 0;
for (int i = 0; i < n / 2; i++)
for (int j = 0; j < n / 2; j++)
sum += max(a[i][j], a[i][n - j - 1], a[n - i - 1][j], a[n - i - 1][n - j - 1]);