Harvester (Codeforces 1219G)
Tags: Implement, implementation

It is Bubble Cup finals season and farmer Johnny Bubbles must harvest his bubbles. The bubbles are in a rectangular bubblefield formed of $$$N$$$ x $$$M$$$ square parcels divided into $$$N$$$ rows and $$$M$$$ columns. The parcel in $$$i^{th}$$$ row and $$$j^{th}$$$ column yields $$$A_{i,j}$$$ bubbles.Johnny Bubbles has available a very special self-driving bubble harvester that, once manually positioned at the beginning of a row or column, automatically harvests all the bubbles in that row or column. Once the harvester reaches the end of the row or column it stops and must be repositioned. The harvester can pass through any parcel any number of times, but it can collect bubbles from the parcel only once.Johnny is very busy farmer, so he is available to manually position the harvester at most four times per day. Johnny is also impatient, so he wants to harvest as many bubbles as possible on the first day.Please help Johnny to calculate what is the maximum number of bubbles he can collect on the first day.

Input: The first line contains two integers $$$N$$$ and $$$M$$$ ($$$1$$$ $$$\leq$$$ $$$N$$$, $$$M$$$ $$$\leq$$$ $$$N$$$ * $$$M$$$ $$$\leq$$$ $$$10^{5}$$$) - the bubblefield size.Each of the next $$$N$$$ lines contains $$$M$$$ integers. The $$$j^{th}$$$ element in the $$$i^{th}$$$ line is $$$A_{i,j}$$$ ($$$0$$$ $$$\leq$$$ $$$a_{i,j}$$$ $$$\leq$$$ $$$10^{9}$$$) — the yield of the parcel located in the $$$i^{th}$$$ row and the $$$j^{th}$$$ column.

Output: Output contains one integer number - maximum number of the bubbles Johnny can harvest on the first day.

Note: In the first example, farmer Johnny can harvest all the bubbles by positioning the harvester on the first and the second row.In the second example, one way Johnny can harvest maximum number of bubbles is to position the harvester in the second row, the fourth row, the second column and the fourth column.

Sample Inputs:
2 2
1 2
3 4

5 5
0 9 2 7 0
9 0 3 0 5
0 8 0 3 1
6 7 4 3 9
3 6 4 1 0

Sample Outputs:
10

80

Solution (Python):
def oneRow(grid, n, m, rowSums, colSums):
    ans = 0.0
    for takenRow in range(n):
        rowSum = rowSums[takenRow]
        maxColSums = [0, 0, 0]
        for col in range(m):
            colSum = colSums[col] - grid[takenRow][col]
            if colSum >= maxColSums[0]:
                maxColSums[2] = maxColSums[1]
                maxColSums[1] = maxColSums[0]
                maxColSums[0] = colSum
            elif colSum >= maxColSums[1]:
                maxColSums[2] = maxColSums[1]
                maxColSums[1] = colSum
            elif colSum >= maxColSums[2]:
                maxColSums[2] = colSum
        colSum = maxColSums[0] + maxColSums[1] + maxColSums[2]
        ans = max(ans, rowSum + colSum)
    return ans

def twoRows(grid, n, m, rowSums, colSums):
    ans = 0.0
    for takenRow1 in range(n):
        rowSum1 = rowSums[takenRow1]
        for takenRow2 in range(takenRow1 + 1, n):
            rowSum2 = rowSums[takenRow2]
            maxColSums = [0, 0]
            for col in range(m):
                colSum = colSums[col] - grid[takenRow1][col] - grid[takenRow2][col]
                if colSum >= maxColSums[0]:
                    maxColSums[1] = maxColSums[0]
                    maxColSums[0] = colSum
                elif colSum >= maxColSums[1]:
                    maxColSums[1] = colSum
            colSum = maxColSums[0] + maxColSums[1]
            ans = max(ans, rowSum1 + rowSum2 + colSum)
    return ans

def main():
    (n, m) = readIntArr()
    grid = []
    for _ in range(n):
        grid.append(readFloatArr())
    if n <= 4 or m <= 4:
        ans = 0
        for i in range(n):
            for j in range(m):
                ans += grid[i][j]
        ans = int(ans + 1e-06)
        print(ans)
        return
    grid2 = []
    (M, N) = (n, m)
    for j in range(m):
        row = []
        for i in range(n):
            row.append(grid[i][j])
        grid2.append(row)
    if n < m:
        temp = grid
        grid = grid2
        grid2 = temp
        temp = n
        n = m
        m = temp
        temp = N
        N = M
        M = temp
    rowSums = []
    for i in range(n):
        s = 0
        for j in range(m):
            s += grid[i][j]
        rowSums.append(s)
    colSums = []
    for j in range(m):
        s = 0
        for i in range(n):
            s += grid[i][j]
        colSums.append(s)
    ans1 = oneRow(grid, n, m, rowSums, colSums)
    ans2 = twoRows(grid, n, m, rowSums, colSums)
    ans3 = oneRow(grid2, N, M, colSums, rowSums)
    rowSums.sort(reverse=True)
    ans4 = 0
    for i in range(4):
        ans4 += rowSums[i]
    colSums.sort(reverse=True)
    ans5 = 0
    for i in range(4):
        ans5 += colSums[i]
    ans = max(ans1, ans2, ans3, ans4, ans5)
    ans = int(ans + 1e-06)
    print(ans)
    return
import sys
input = sys.stdin.buffer.readline

def oneLineArrayPrint(arr):
    print(' '.join([str(x) for x in arr]))

def multiLineArrayPrint(arr):
    print('\n'.join([str(x) for x in arr]))

def multiLineArrayOfArraysPrint(arr):
    print('\n'.join([' '.join([str(x) for x in y]) for y in arr]))

def readIntArr():
    return [int(x) for x in input().split()]

def readFloatArr():
    return [float(x) for x in input().split()]

def makeArr(defaultValFactory, dimensionArr):
    dv = defaultValFactory
    da = dimensionArr
    if len(da) == 1:
        return [dv() for _ in range(da[0])]
    else:
        return [makeArr(dv, da[1:]) for _ in range(da[0])]

def queryInteractive(i, j):
    print('? {} {}'.format(i, j))
    sys.stdout.flush()
    return int(input())

def answerInteractive(ans):
    print('! {}'.format(' '.join([str(x) for x in ans])))
    sys.stdout.flush()
inf = float('inf')
MOD = 10 ** 9 + 7
for _abc in range(1):
    main()

Solution (Python):
import sys
input = sys.stdin.buffer.readline
from itertools import combinations

def process(A):
    n = len(A)
    m = len(A[0])
    rows = [[0, i, 'r'] for i in range(n)]
    cols = [[0, j, 'c'] for j in range(m)]
    for i in range(n):
        for j in range(m):
            x = A[i][j]
            rows[i][0] += x
            cols[j][0] += x
    rows = sorted(rows)
    cols = sorted(cols)
    rows2 = rows[max(n - 4, 0):n]
    cols2 = cols[max(m - 4, 0):m]
    answer = 0
    for i in range(len(rows2) + 1):
        for j in range(min(5 - i, len(cols2) + 1)):
            for my_rows in combinations(rows2, i):
                for my_cols in combinations(cols2, j):
                    value = 0
                    for (a, I, t) in my_rows:
                        value += a
                    for (b, J, t2) in my_cols:
                        value += b
                    for (a, I, t) in my_rows:
                        for (b, J, t2) in my_cols:
                            value -= A[I][J]
                    answer = max(answer, value)
    return answer
(n, m) = [int(x) for x in input().split()]
A = []
for i in range(n):
    row = [int(x) for x in input().split()]
    A.append(row)
print(process(A))

Solution (Python):
import sys
from array import array

def finish(rep, su):
    ret = 0
    for i in range(rep):
        ma = max(su)
        su.remove(ma)
        ret += ma
    return ret
input = lambda : sys.stdin.buffer.readline().decode().strip()
(n, m) = map(int, input().split())
a = [array('i', [int(x) for x in input().split()]) for _ in range(n)]
(sur, suc, ans) = ([0] * n, [0] * m, 0)
for i in range(n):
    for j in range(m):
        sur[i] += a[i][j]
        suc[j] += a[i][j]
(sur31, suc31) = ([sur[:] for _ in range(m)], [suc[:] for _ in range(n)])
for i in range(n):
    for j in range(m):
        sur31[j][i] -= a[i][j]
        suc31[i][j] -= a[i][j]
for i in range(n):
    ans = max(ans, sur[i] + finish(min(3, m), suc31[i]))
for i in range(m):
    ans = max(ans, suc[i] + finish(min(3, n), sur31[i]))
if n >= m:
    for c1 in range(m):
        for c2 in range(c1 + 1, m):
            su = []
            for i in range(n):
                su.append(sur[i] - a[i][c1] - a[i][c2])
            ans = max(ans, suc[c1] + suc[c2] + finish(2, su))
else:
    for r1 in range(n):
        for r2 in range(r1 + 1, n):
            su = []
            for i in range(m):
                su.append(suc[i] - a[r1][i] - a[r2][i])
            ans = max(ans, sur[r1] + sur[r2] + finish(2, su))
ans = max(finish(min(4, m), suc), finish(min(4, n), sur), ans)
print(ans)