Corners (Codeforces 1720C)
Tags: Greedy, implementation

You are given a matrix consisting of $$$n$$$ rows and $$$m$$$ columns. Each cell of this matrix contains $$$0$$$ or $$$1$$$.Let's call a square of size $$$2 \times 2$$$ without one corner cell an L-shape figure. In one operation you can take one L-shape figure, with at least one cell containing $$$1$$$ and replace all numbers in it with zeroes.Find the maximum number of operations that you can do with the given matrix.

Input: The first line contains one integer $$$t$$$ ($$$1 \leq t \leq 500$$$) — the number of test cases. Then follow the descriptions of each test case.The first line of each test case contains two integers $$$n$$$ and $$$m$$$ ($$$2 \leq n, m \leq 500$$$) — the size of the matrix.Each of the following $$$n$$$ lines contains a binary string of length $$$m$$$ — the description of the matrix.It is guaranteed that the sum of $$$n$$$ and the sum of $$$m$$$ over all test cases does not exceed $$$1000$$$.

Output: For each test case output the maximum number of operations you can do with the given matrix.

Note: In the first testcase one of the optimal sequences of operations is the following (bold font shows l-shape figure on which operation was performed):   Matrix before any operation was performed:  101111011110  Matrix after $$$1$$$ operation was performed:  100101011110  Matrix after $$$2$$$ operations were performed:  100100011110  Matrix after $$$3$$$ operations were performed:  100100010110  Matrix after $$$4$$$ operations were performed:  100000010110  Matrix after $$$5$$$ operations were performed:  100000010100  Matrix after $$$6$$$ operations were performed:  100000000100  Matrix after $$$7$$$ operations were performed:  000000000100  Matrix after $$$8$$$ operations were performed:  000000000000 In the third testcase from the sample we can not perform any operation because the matrix doesn't contain any ones.In the fourth testcase it does not matter which L-shape figure we pick in our first operation. We will always be left with single one. So we will perform $$$2$$$ operations.

Sample Inputs:
4
4 3
101
111
011
110
3 4
1110
0111
0111
2 2
00
00
2 2
11
11

Sample Outputs:
8
9
0
2

Solution (Python):
def main():
    (n, m) = map(int, input().split())
    l = []
    count = 0
    for i in range(n):
        a = input()
        l.append(a)
        count += a.count('1')
    if count == n * m:
        print(count - 2)
        return
    if count == n * m - 1:
        print(count - 1)
        return
    for i in range(n):
        for j in range(m):
            if j + 1 < m and l[i][j] == '0' and (l[i][j + 1] == '0'):
                print(count)
                return
            if j - 1 >= 0 and i + 1 < n and (l[i][j] == '0') and (l[i + 1][j - 1] == '0'):
                print(count)
                return
            if i + 1 < n and l[i][j] == '0' and (l[i + 1][j] == '0'):
                print(count)
                return
            if j + 1 < m and i + 1 < n and (l[i][j] == '0') and (l[i + 1][j + 1] == '0'):
                print(count)
                return
    print(count - 1)
    return
for i in range(int(input())):
    main()

Solution (Python):
def solve():
    (n, m) = map(int, input().split())
    a = []
    (zero, one) = (0, 0)
    for i in range(n):
        r = input()
        a.append(list(r))
        zero += r.count('0')
        one += r.count('1')
    if zero == 0:
        print(one - 2)
        return
    if zero == 1:
        print(one - 1)
        return
    for r in range(n - 1):
        for c in range(m - 1):
            t = []
            t.append(a[r][c])
            t.append(a[r][c + 1])
            t.append(a[r + 1][c])
            t.append(a[r + 1][c + 1])
            if t.count('0') >= 2:
                print(one)
                return
    print(one - 1)
for _ in range(int(input())):
    solve()

Solution (Python):
testnum = int(input())
for testcount in range(testnum):
    (n, m) = map(int, input().split())
    znum = 0
    dz = False
    l = []
    for i in range(n):
        s = input()
        znum += s.count('0')
        if not dz:
            l.append('1' + s + '1')
            if s.find('00') >= 0:
                dz = True
    if znum <= 1:
        print(n * m - 2)
        continue
    for i in range(n - 1):
        if dz:
            break
        for j in range(1, m + 1):
            if l[i][j] == '0' and l[i + 1][j - 1:j + 2].find('0') >= 0:
                dz = True
                break
    if dz:
        print(n * m - znum)
    else:
        print(n * m - znum - 1)