Search code examples
algorithmdata-structurestime-complexity

Largest sum of upper-left quadrant of matrix that can be formed by reversing rows and columns


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:

  • It is not possible to get any configuration from reversing rows and columns. Therefore, the answer cannot be to simply sort all the elements and sum the top NxN of them.
  • Furthermore, it is not possible to move any 1 element to any other position. For example, the only possibly places for the element at (N-1,N-1) to be moved are (0,N-1),(N-1,0),(0,0).
  • It requires 1 row reversal to get an element from the upper-right or bottom-left quadrant to the upper-left quadrant, and 2 reversals to get an element from the bottom-right quadrant to the upper-left quadrant.
  • It's not possible to come up with a solution that simply looks at each element in the upper-left quadrant and checks whether it can be replaced by a larger element in the range of elements that can be moved in it's place (e.g. 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. :)


Solution

  • 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]);