Robot and Candies (Codeforces 1611G)
Tags: Greedy, graph matchings

Polycarp has a rectangular field of $$$n \times m$$$ cells (the size of the $$$n \cdot m$$$ field does not exceed $$$10^6$$$ cells, $$$m \ge 2$$$), in each cell of which there can be candy. There are $$$n$$$ rows and $$$m$$$ columns in the field.Let's denote a cell with coordinates $$$x$$$ vertically and $$$y$$$ horizontally by $$$(x, y)$$$. Then the top-left cell will be denoted as $$$(1, 1)$$$, and the bottom-right cell will be denoted as $$$(n, m)$$$.If there is candy in the cell, then the cell is marked with the symbol '1', otherwise — with the symbol '0'.Polycarp made a Robot that can collect candy. The Robot can move from $$$(x, y)$$$ either to $$$(x+1, y+1)$$$, or to $$$(x+1, y-1)$$$. If the Robot is in a cell that contains candy, it takes it.While there is at least one candy on the field, the following procedure is executed:   Polycarp puts the Robot in an arbitrary cell on the topmost row of the field. He himself chooses in which cell to place the Robot. It is allowed to put the Robot in the same cell multiple times.  The Robot moves across the field and collects candies. He controls the Robot.  When the Robot leaves the field, Polycarp takes it. If there are still candies left, Polycarp repeats the procedure. Find the minimum number of times Polycarp needs to put the Robot on the topmost row of the field in order to collect all the candies. It is guaranteed that Polycarp can always collect all the candies.

Input: The first line of input data contains an integer $$$t$$$ ($$$1 \le t \le 10^4$$$) — the number of input data sets in the test.Before each input data, there is a blank line in the test. Next is a line that contains integers $$$n$$$ and $$$m$$$ ($$$2 \le m$$$, $$$2 \le n \cdot m \le 10^6$$$) — field sizes. This is followed by $$$n$$$ lines, $$$i$$$-th of which describes the $$$i$$$-th line of the field. Each of them is a string of size $$$m$$$ characters: the symbol '1' corresponds to a cell with candy, the symbol '0' — an empty cell.It is guaranteed that the sum of $$$n \cdot m$$$ values for all input data sets in the test does not exceed $$$10^6$$$.

Output: Print $$$t$$$ lines, each line should contain the answer to the corresponding set of input data: the minimum number of times Polycarpus needs to put the Robot on the topmost row of the field in order to collect all the candies.

Note: In the first set Polycarp may not put the Robot on the field at all, so the answer "0"In the second set, Polycarp will need to place the robot on the field twice. The Robot can collect candies like this: for the first time Polycarp puts the Robot in the cell $$$(1, 1)$$$ and collects candies at the positions $$$(1, 1)$$$ and $$$(3, 3)$$$. The second time Polycarp can again put the Robot in $$$(1, 1)$$$, and then the Robot will move first to $$$(2,2)$$$, then to $$$(3, 1)$$$ and collect the last candy.In the fourth set, you can show that the Robot cannot collect all the candies in three passes.

Sample Inputs:
4

2 2
00
00

3 3
100
000
101

4 5
01000
00001
00010
10000

3 3
111
111
111

Sample Outputs:
0
2
2
4

Solution (Python):
import sys
I = sys.stdin.readline

def f(s, e, l):
    while s <= e:
        if l[s]:
            return s
        s += 2
for _ in [0] * int(I()):
    I()
    (n, m) = map(int, I().split())
    s = [I() for i in range(n)]
    n -= 1
    d = [0] * (n + m)
    for i in range(n + m):
        (r, c, e) = (min(i, n), max(0, i - n), min(i, m - 1))
        while r >= 0 and c < m:
            if s[r][c] > '0':
                p = f(c - r, e, d)
                if p == None:
                    d[c - r] = 1
                    break
                else:
                    (d[p], d[c - r], c, r) = (0, 1, (i + p) // 2, (i - p) // 2)
            r -= 1
            c += 1
    print(sum(d))

Solution (Python):
import sys
I = sys.stdin.readline

def f(s, e, l):
    while s <= e:
        if l[s]:
            return s
        s += 2
for _ in [0] * int(I()):
    I()
    (n, m) = map(int, I().split())
    s = [I() for i in range(n)]
    n -= 1
    d = [0] * (n + m)
    for i in range(n + m):
        (r, c, e) = (min(i, n), max(0, i - n), min(i, m - 1))
        while r >= 0 and c < m:
            if s[r][c] > '0':
                p = f(c - r, e, d)
                if p == None:
                    d[c - r] = 1
                    break
                else:
                    (d[p], d[c - r], c, r) = (0, 1, (i + p) // 2, (i - p) // 2)
            r -= 1
            c += 1
    print(sum(d))

Solution (Python):
import sys
I = sys.stdin.readline

def f(s, e, l):
    while s <= e:
        if l[s]:
            return s
        s += 2
for _ in range(int(input())):
    I()
    (n, m) = map(int, I().split())
    s = [I() for i in range(n)]
    n -= 1
    d = [0] * (n + m)
    for i in range(n + m):
        (r, c, e) = (min(i, n), max(0, i - n), min(i, m - 1))
        while r >= 0 and c < m:
            if s[r][c] > '0':
                p = f(c - r, e, d)
                if p == None:
                    d[c - r] = 1
                    break
                else:
                    (d[p], d[c - r], c, r) = (0, 1, (i + p) // 2, (i - p) // 2)
            r -= 1
            c += 1
    print(sum(d))