Robot on the Board 2 (Codeforces 1607F)
Tags: Implement, graphs

The robot is located on a checkered rectangular board of size $$$n \times m$$$ ($$$n$$$ rows, $$$m$$$ columns). The rows in the board are numbered from $$$1$$$ to $$$n$$$ from top to bottom, and the columns — from $$$1$$$ to $$$m$$$ from left to right.The robot is able to move from the current cell to one of the four cells adjacent by side.Each cell has one of the symbols 'L', 'R', 'D' or 'U' written on it, indicating the direction in which the robot will move when it gets in that cell — left, right, down or up, respectively.The robot can start its movement in any cell. He then moves to the adjacent square in the direction indicated on the current square in one move.   If the robot moves beyond the edge of the board, it falls and breaks.  If the robot appears in the cell it already visited before, it breaks (it stops and doesn't move anymore). Robot can choose any cell as the starting cell. Its goal is to make the maximum number of steps before it breaks or stops.Determine from which square the robot should start its movement in order to execute as many commands as possible. A command is considered successfully completed if the robot has moved from the square on which that command was written (it does not matter whether to another square or beyond the edge of the board).

Input: The first line contains an integer $$$t$$$ ($$$1 \le t \le 10000$$$) — the number of test cases in the test.Each test case's description is preceded by a blank line. Next is a line that contains integers $$$n$$$ and $$$m$$$ ($$$1 \le n \le 2000$$$; $$$1 \le m \le 2000$$$) — the height and width of the board. This line followed by $$$n$$$ lines, the $$$i$$$-th of which describes the $$$i$$$-th line of the board. Each of them is exactly $$$m$$$ letters long and consists of symbols 'L', 'R', 'D' and 'U'.It is guaranteed that the sum of sizes of all boards in the input does not exceed $$$4\cdot10^6$$$.

Output: For each test case, output three integers $$$r$$$, $$$c$$$ and $$$d$$$ ($$$1 \le r \le n$$$; $$$1 \le c \le m$$$; $$$d \ge 0$$$), which denote that the robot should start moving from cell $$$(r, c)$$$ to make the maximum number of moves $$$d$$$. If there are several answers, output any of them.


Sample Inputs:
7

1 1
R

1 3
RRL

2 2
DL
RU

2 2
UD
RU

3 2
DL
UL
RU

4 4
RRRD
RUUD
URUD
ULLR

4 4
DDLU
RDDU
UUUU
RDLD

Sample Outputs:
1 1 1
1 1 3
1 1 4
2 1 3
3 1 5
4 3 12
1 1 4

Solution (Python):
import io, os
input = io.BytesIO(os.read(0, os.fstat(0).st_size)).readline

def main(t):
    s = input()
    (m, n) = map(int, input().split())
    grid = []
    for i in range(m):
        grid.append(input())
    nextindex = [-1] * (m * n)
    away = [0] * (m * n + 1)
    direc = {ord('U'): [-1, 0], ord('D'): [1, 0], ord('L'): [0, -1], ord('R'): [0, 1]}
    visited = [False] * (m * n)
    indegree = [0] * (m * n)
    for i in range(m):
        for j in range(n):
            index = i * n + j
            newi = i + direc[grid[i][j]][0]
            newj = j + direc[grid[i][j]][1]
            if newi < 0 or newi >= m or newj < 0 or (newj >= n):
                continue
            nextindex[index] = newi * n + newj
            indegree[newi * n + newj] += 1
    for index in range(m * n):
        if indegree[index] > 0:
            continue
        seq = []
        while not visited[index] and index != -1 and (away[index] == 0):
            seq.append(index)
            visited[index] = True
            index = nextindex[index]
        if index < 0:
            for (i, ind) in enumerate(seq):
                away[ind] = len(seq) - i
        else:
            base = away[index]
            flag = False
            loop = len(seq)
            for (i, ind) in enumerate(seq):
                if ind == index:
                    flag = True
                if not flag:
                    loop -= 1
                away[ind] = max(len(seq) - i, loop) + base
    for index in range(m * n):
        if away[index] > 0:
            continue
        loop = 0
        seq = []
        while not visited[index]:
            seq.append(index)
            visited[index] = True
            index = nextindex[index]
            loop += 1
        for num in seq:
            away[num] = loop
    maximum = max(away)
    for i in range(m * n):
        if away[i] == maximum:
            print(i // n + 1, i % n + 1, away[i])
            return
T = int(input())
t = 1
while t <= T:
    main(t)
    t += 1

Solution (Python):
import os, sys
input = lambda : sys.stdin.buffer.readline().rstrip(b'\r\n')

def dbp(*args, **kwargs):
    print(*args, file=sys.stderr, **kwargs)
a_str = lambda : input().decode('ascii')
get_int_list = lambda : [int(x) for x in input().split()]
join_str = lambda l, ch=' ': ch.join((str(x) for x in l))

def do_thing():
    input()
    (R, C) = get_int_list()
    dd = {'L': -1, 'U': -2, 'R': -3, 'D': -4}
    g = [[0] * (C + 2)] + [[0] + [dd[ch] for ch in a_str()] + [0] for _ in range(R)] + [[0] * (C + 2)]
    dr = {-1: 0, -2: -1, -3: 0, -4: 1}
    dc = {-1: -1, -2: 0, -3: 1, -4: 0}
    maxpath = float('-inf')
    best = []
    for sr in range(1, R + 1):
        for sc in range(1, C + 1):
            (r, c) = (sr, sc)
            dv = g[r][c]
            if dv >= 0:
                continue
            path = []
            upstep = -5
            while -5 < g[r][c] < 0:
                path.append((r, c))
                g[r][c] = upstep
                upstep -= 1
                r += dr[dv]
                c += dc[dv]
                dv = g[r][c]
            if dv < -4:
                cyclelength = dv - upstep
                while g[r][c] <= dv:
                    g[r][c] = cyclelength
                    (r, c) = path.pop()
            step = g[r][c]
            for (r, c) in reversed(path):
                step += 1
                g[r][c] = step
            if step == maxpath:
                best.append((r, c))
            elif step > maxpath:
                maxpath = step
                best = [(r, c)]
    return join_str((best[0][0], best[0][1], maxpath))
if __name__ == '__main__':
    maxcc = 1
    maxcc = int(input())
    for cc in range(maxcc):
        print(do_thing())

Solution (Python):
import sys
sys.setrecursionlimit(100000)

def _r():
    return sys.stdin.buffer.readline()

def rs():
    return _r().decode('ascii').strip()

def rn():
    return int(_r())

def rnt():
    return tuple(map(int, _r().split()))

def rnl():
    return list(rnt())
from array import array

def solve(n, m, mat):
    dirs = {'L': (0, -1), 'R': (0, 1), 'U': (-1, 0), 'D': (1, 0)}
    dp = [array('l', [0] * m) for _ in range(n)]
    seen = [array('l', [-1] * m) for _ in range(n)]
    path = array('l', [0] * (n * m))

    def _doit(r, c):
        steps = 0
        while 0 <= r < n and 0 <= c < m and (seen[r][c] == -1) and (dp[r][c] == 0):
            seen[r][c] = steps
            path[steps] = 10000 * r + c
            steps += 1
            (dr, dc) = dirs[mat[r][c]]
            (r, c) = (r + dr, c + dc)
        cycle = seen[r][c] if 0 <= r < n and 0 <= c < m and (dp[r][c] == 0) else n * m
        d = dp[r][c] if 0 <= r < n and 0 <= c < m else 0
        for v in range(steps):
            (r, c) = divmod(path[v], 10000)
            dp[r][c] = steps - min(v, cycle) + d
    sr = sc = 0
    for r in range(n):
        for c in range(m):
            if dp[r][c] == 0:
                _doit(r, c)
            if dp[r][c] > dp[sr][sc]:
                (sr, sc) = (r, c)
    return (sr + 1, sc + 1, dp[sr][sc])
for _ in range(rn()):
    rs()
    (n, m) = rnt()
    mat = []
    for _ in range(n):
        mat.append(rs())
    print(' '.join(map(str, solve(n, m, mat))))