Problem:


Score : 400 points

Problem Statement

A maze is composed of a grid of H \times W squares - H vertical, W horizontal.

The square at the i-th row from the top and the j-th column from the left - (i,j) - is a wall if S_{ij} is # and a road if S_{ij} is ..

There is a magician in (C_h,C_w). He can do the following two kinds of moves:

Move A: Walk to a road square that is vertically or horizontally adjacent to the square he is currently in.

Move B: Use magic to warp himself to a road square in the 5\times 5 area centered at the square he is currently in.

In either case, he cannot go out of the maze.

At least how many times does he need to use the magic to reach (D_h, D_w)?

Constraints

1 \leq H,W \leq 10^3

1 \leq C_h,D_h \leq H

1 \leq C_w,D_w \leq W

S_{ij} is # or ..

S_{C_h C_w} and S_{D_h D_w} are ..

(C_h,C_w) \neq (D_h,D_w)

Input

Input is given from Standard Input in the following format:

H W
C_h C_w
D_h D_w
S_{11}\ldots S_{1W}
\vdots
S_{H1}\ldots S_{HW}

Output

Print the minimum number of times the magician needs to use the magic. If he cannot reach (D_h,D_w), print -1 instead.

Sample Input 1

4 4
1 1
4 4
..#.
..#.
.#..
.#..

Sample Output 1

1

For example, by walking to (2,2) and then using the magic to travel to (4,4), just one use of magic is enough.

Note that he cannot walk diagonally.

Sample Input 2

4 4
1 4
4 1
.##.
####
####
.##.

Sample Output 2

-1

He cannot move from there.

Sample Input 3

4 4
2 2
3 3
....
....
....
....

Sample Output 3

0

No use of magic is needed.

Sample Input 4

4 5
1 2
2 5
#.###
####.
#..##
#..##

Sample Output 4

2



Sample input:
4 4
1 1
4 4
..#.
..#.
.#..
.#..


Sample output:
1

Submission status: Accepted

Solution code:
#import sys
MOD = 10 ** 9 + 7
INFI = 10**10
#input = sys.stdin.readline
import math
from collections import deque
import itertools
import heapq
#import bisect
from fractions import Fraction
import copy
from functools import lru_cache
from collections import defaultdict
import pprint

#oo=list("ABCDEFGHIJKLMNOPQRSTUVWXYZ")
# ko=list("abcdefghijklmnopqrstuvwxyz")

def sosuhante(n):
    for k in range(2, int(math.sqrt(n))+1):
        if n% k ==0:
            return False
    return True
def cmb(n, r):
    if n - r < r: r = n - r
    if r == 0: return 1
    if r == 1: return n

    numerator = [n - r + k + 1 for k in range(r)]
    denominator = [k + 1 for k in range(r)]

    for p in range(2,r+1):
        pivot = denominator[p - 1]
        if pivot > 1:
            offset = (n - r) % p
            for k in range(p-1,r,p):
                numerator[k - offset] /= pivot
                denominator[k] /= pivot

    result = 1
    for k in range(r):
        if numerator[k] > 1:
            result *= int(numerator[k])

    return result

def kingaku(a,b,n):
    keta=len(str(n))
    return a*n+b*keta

def my_index(l, x, default=False):
    if x in l:
        return l.index(x)
    else:
        return default

#    h,w,a,b = map(int, input().split())
#    c = [[0 for j in range(n)] for i in range(n)]

def ret(a):
    c=[None]*(len(a)-1)
    if len(a)==1:
        return a[0]
    elif len(a)==0:
        return 0
    for i in range(1,len(a)):
        c[i-1]=abs(a[i]-a[i-1])
    return ret(c)

def soinsubunkai(n):
    a = []
    i = 1
    while i*i <= n:
        if n % i == 0 and i!=1:
            a.append(i)
            n=n//i

        if n% i !=0 or i==1:
            i += 1
    nokori=[n]
    return a + nokori

def make_divisors(n):
    lower_divisors , upper_divisors = [], []
    i = 1
    while i*i <= n:
        if n % i == 0:
            lower_divisors.append(i)
            if i != n // i:
                upper_divisors.append(n//i)
        i += 1
    return lower_divisors + upper_divisors[::-1]

def main():
    #l,r,d=map(int,input().split())
    h,w= map(int, input().split())
    cx,cy = map(int, input().split())
    dx,dy = map(int, input().split())
    s=[]
    s.append(list("#"*(w+4)))
    s.append(list("#"*(w+4)))
    for i in range(h):
        temp=input()
        temp="##"+temp+"##"
        s.append(list(temp))
    s.append(list("#"*(w+4)))
    s.append(list("#"*(w+4)))
#    for i in range(h+4):
#        print(s[i])

    visited = [[0 for i in range(w+4)] for _ in range(h+4)]
    warpvisited = [[0 for i in range(w + 4)] for _ in range(h + 4)]
    warp = [[INFI for i in range(w+4)] for _ in range(h+4)]
    visited[cx+1][cy+1]=1
    warp[cx+1][cy+1]=0

    queue = deque([])

    warpdire=[[-2,-2],[-1,-2],[0,-2],[1,-2],[2,-2],
           [-2,-1],[-1,-1],[1,-1],[2,-1],
           [-2,0],[2,0],
           [-2,1],[-1,1],[1,1],[2,1],
           [-2,2],[-1,2],[0,2],[1,2],[2,2],
              [0,-1],[-1,0],[1,0],[0,1]]
    walkdire=[[0,-1],[-1,0],[1,0],[0,1]]

    warpvisited = [[0 for i in range(w + 4)] for _ in range(h + 4)]
    walkvisited = [[0 for i in range(w + 4)] for _ in range(h + 4)]
    rekkyo=[]
    rekkyo2=[]
    nowx = cx + 1
    nowy = cy + 1
    def walkloop(nowx,nowy):
        walkvisited[nowx][nowy]=1
        rekkyo.append([nowx,nowy])
        for i in walkdire:
            if s[nowx + i[0]][nowy + i[1]] == "." and walkvisited[nowx + i[0]][nowy + i[1]] == 0:
                queue.append([nowx + i[0], nowy + i[1]])
                warp[nowx + i[0]][nowy + i[1]] = min(warp[nowx][nowy], warp[nowx + i[0]][nowy + i[1]])
                visited[nowx + i[0]][nowy + i[1]] = 1
                walkvisited[nowx + i[0]][nowy + i[1]] = 1
                rekkyo.append([nowx+i[0],nowy+i[1]])
        while queue:
            if len(queue) <= 0:
                return
            now = queue.popleft()
            nowx = now[0]
            nowy = now[1]


            for i in walkdire:
                if s[nowx + i[0]][nowy + i[1]] == "." and walkvisited[nowx + i[0]][nowy + i[1]] == 0:
                    queue.append([nowx + i[0], nowy + i[1]])
                    warp[nowx + i[0]][nowy + i[1]] = min(warp[nowx][nowy], warp[nowx + i[0]][nowy + i[1]])
                    visited[nowx + i[0]][nowy + i[1]] = 1
                    walkvisited[nowx + i[0]][nowy + i[1]] = 1
                    rekkyo.append([nowx + i[0], nowy + i[1]])

        return
    def warploop(nowx,nowy,cost):
        for i in warpdire:
            if s[nowx + i[0]][nowy + i[1]] == "." and warp[nowx + i[0]][nowy + i[1]]>cost:

                warp[nowx + i[0]][nowy + i[1]] = min(warp[nowx][nowy]+1, warp[nowx + i[0]][nowy + i[1]])
                visited[nowx + i[0]][nowy + i[1]] = 1
                warpvisited[nowx + i[0]][nowy + i[1]] = 1
                rekkyo2.append([nowx+i[0],nowy+i[1]])
        return
    cost=0
    walkloop(cx + 1, cy + 1)
    cost += 1

    while True:
        for i in rekkyo:
            warploop(i[0],i[1],cost)
        rekkyo=[]
 #       print(rekkyo2)
        for i in rekkyo2:
            walkloop(i[0],i[1])
        rekkyo2=[]
   #     print(rekkyo)
        if len(rekkyo)==0:
            break

        cost+=1


    if visited[dx+1][dy+1]==0:
        print("-1")
    else:
        print(warp[dx+1][dy+1])

#    for i in range(h+4):
 #       print(visited[i])
 #   for i in range(h+4):
 #      print(warp[i])




if __name__ == "__main__":

    main()

Submission status: Accepted

Solution code:
import sys, math
from collections import defaultdict, deque, Counter
#from bisect import bisect_left, bisect_right
#from itertools import combinations, permutations, product
from heapq import heappush, heappop
#from functools import lru_cache
input = sys.stdin.readline
rs = lambda: input().strip()
ri = lambda: int(input())
rl = lambda: list(map(int, input().split()))
mod = 1000000007
sys.setrecursionlimit(1000000)

H, W = rl()
C = rl()
D = rl()
M = []
for i in range(H):
	s = rs()
	M.append(s)

start = tuple([C[0]-1, C[1]-1])
end = tuple([D[0]-1, D[1]-1])

queue = deque()
queue.append((start, 0))
visited = [[float('inf')]*W for _ in range(H)]
visited[start[0]][start[1]] = 0

ds = [(1,0),(-1,0),(0,1),(0,-1)]
while queue:
	n, d = queue.popleft()
	if n == end:
		print(d)
		exit()
	i, j = n
	if visited[i][j] != d:
		continue
	nd = d
	for di, dj in ds:
		ni, nj = i+di, j+dj
		if not (0 <= ni < H and 0 <= nj < W): continue
		if M[ni][nj] == '#': continue
		if nd < visited[ni][nj]:
			queue.appendleft(((ni,nj), nd))
			visited[ni][nj] = nd
	nd = d+1
	for di in range(-2, 3):
		for dj in range(-2, 3):
			if (di, dj) == (0,0): continue
			ni, nj = i+di, j+dj
			if not (0 <= ni < H and 0 <= nj < W): continue
			if M[ni][nj] == '#': continue
			if nd < visited[ni][nj]:
				queue.append(((ni,nj), nd))
				visited[ni][nj] = nd
print(-1)

Submission status: Accepted

Solution code:
from collections import deque
H, W = map(int, input().split())
ch, cw = map(int, input().split())
dh_, dw_ = map(int, input().split())

fs = []
for i in range(H):
    r = list(input())
    fs.append(r)

walks = [(-1,0),(1,0),(0,1),(0,-1)]
magics = []
for i in range(-2,3):
    for j in range(-2,3):
        if i==j==0:continue
        if (i,j) not in walks:
            magics.append((i,j))

INF = 1 << 50
dps = [[INF]*W for i in range(H)]
dps[ch-1][cw-1] = 0
q = deque([])
q.appendleft((ch-1,cw-1,0))
while len(q)>0:
    h,w,cnt = q.popleft()
    if cnt > dps[h][w]:continue
    dps[h][w] = cnt
    for dh, dw in walks:
        hn = h + dh
        wn = w + dw
        if 0<=hn<H and 0<=wn<W:
            if dps[hn][wn] != INF:continue
            if fs[hn][wn] == ".":
                q.appendleft((hn, wn, cnt))
    for dh, dw in magics:
        hn = h + dh
        wn = w + dw
        if 0<=hn<H and 0<=wn<W:
            if dps[hn][wn] != INF:continue
            if fs[hn][wn] == ".":
                q.append((hn, wn, cnt+1))

ans = dps[dh_-1][dw_-1]
print(ans if ans != INF else -1)

Submission status: Accepted

Solution code:
#!/usr/bin/env python3
from collections import defaultdict,deque
from heapq import heappush, heappop
from bisect import bisect_left, bisect_right
import sys, random, itertools, math
sys.setrecursionlimit(10**5)
input = sys.stdin.readline
sqrt = math.sqrt
def LI(): return list(map(int, input().split()))
def LF(): return list(map(float, input().split()))
def LI_(): return list(map(lambda x: int(x)-1, input().split()))
def II(): return int(input())
def IF(): return float(input())
def S(): return input().rstrip()
def LS(): return S().split()
def IR(n): return [II() for _ in range(n)]
def LIR(n): return [LI() for _ in range(n)]
def FR(n): return [IF() for _ in range(n)]
def LFR(n): return [LI() for _ in range(n)]
def LIR_(n): return [LI_() for _ in range(n)]
def SR(n): return [S() for _ in range(n)]
def LSR(n): return [LS() for _ in range(n)]
mod = 1000000007
inf = float("INF")

#solve
def solve():
    h, w = LI()
    ch, cw = LI_()
    dh, dw = LI_()
    q = deque()
    s = [None] * h
    c = [None] * h
    for i in range(h):
        s[i] = S()
        c[i] = [inf] * w
    q.append((ch, cw))
    c[ch][cw] = 0
    while q:
        nh, nw = q.popleft()
        now = c[nh][nw]
        for mh, mw in [(0, 1), (1, 0), (-1, 0), (0, -1)]:
            mh += nh
            mw += nw
            if 0 <= mh < h and 0 <= mw < w and c[mh][mw] > now and s[mh][mw] == ".":
                c[mh][mw] = now
                q.appendleft((mh, mw))
        for i in range(-2, 3):
            i += nh
            for j in range(-2, 3):
                j += nw
                if 0 <= i < h and 0 <= j < w and c[i][j] > now + 1 and s[i][j] == ".":
                    c[i][j] = now + 1
                    q.append((i, j))
    print(-1 if c[dh][dw] == inf else c[dh][dw])
    return


#main
if __name__ == '__main__':
    solve()

Submission status: Accepted

Solution code:
import sys
input = sys.stdin.readline
sys.setrecursionlimit(10 ** 7)

h, w = map(int, input().split())
ch, cw = map(int, input().split())
dh, dw = map(int, input().split())
graph = [0] + [0] * h
dist = [0] + [0] * h
for i in range(h):
    graph[i + 1] = [0] + list(input().strip())
    dist[i + 1] = [0] + [-1] * w

from collections import deque

def can_move(graph, dist, next_h, next_w):
    if not ((1 <= next_h <= h) and (1 <= next_w <= w)):
        return False
    if graph[next_h][next_w] == '#':
        return False
    return True

# FYI: https://betrue12.hateblo.jp/entry/2018/12/08/000020
def bfs(graph, queue, dist):
    part = set()
    while queue:
        current_h, current_w = queue.popleft()

        # cost 0
        for dh, dw in ((-1, 0), (1, 0), (0, -1), (0, 1)):
            next_h, next_w = current_h + dh, current_w + dw
            if not can_move(graph, dist, next_h, next_w):
                continue
            # https://atcoder.jp/contests/abc176/editorial/65
            # 解説のとおり、先にワープして到達している場合でも短くなるのであれば上書きする
            # Dijkstraみたいに考える
            if dist[next_h][next_w] == -1 or dist[next_h][next_w] > dist[current_h][current_w]:
                dist[next_h][next_w] = dist[current_h][current_w]
                queue.appendleft((next_h, next_w))

        # cost 1
        for dh in range(-2, 3):
            for dw in range(-2, 3):
                next_h, next_w = current_h + dh, current_w + dw
                if not can_move(graph, dist, next_h, next_w):
                    continue
                if dist[next_h][next_w] != -1:
                    continue
                dist[next_h][next_w] = dist[current_h][current_w] + 1
                queue.append((next_h, next_w))

queue = deque([(ch, cw)])
dist[ch][cw] = 0
bfs(graph, queue, dist)
print(dist[dh][dw])

Submission status: Accepted

Solution code:
import sys, math
from collections import defaultdict, deque, Counter
#from bisect import bisect_left, bisect_right
#from itertools import combinations, permutations, product
from heapq import heappush, heappop
#from functools import lru_cache
input = sys.stdin.readline
rs = lambda: input().strip()
ri = lambda: int(input())
rl = lambda: list(map(int, input().split()))
mod = 1000000007
sys.setrecursionlimit(1000000)

H, W = rl()
C = rl()
D = rl()
M = []
for i in range(H):
	s = rs()
	M.append(s)

start = tuple([C[0]-1, C[1]-1])
end = tuple([D[0]-1, D[1]-1])

queue = deque()
queue.append((start, 0))
visited = defaultdict(lambda: float('inf'))
visited[start] = 0

ds = [(1,0),(-1,0),(0,1),(0,-1)]
while queue:
	n, d = queue.popleft()
	if n == end:
		print(d)
		exit()
	if visited[n] != d:
		continue
	i, j = n
	nd = d
	for di, dj in ds:
		ni, nj = i+di, j+dj
		if not (0 <= ni < H and 0 <= nj < W): continue
		if M[ni][nj] == '#': continue
		if nd < visited[(ni,nj)]:
			queue.appendleft(((ni,nj), nd))
			visited[(ni,nj)] = nd
	nd = d+1
	for di in range(-2, 3):
		for dj in range(-2, 3):
			if (di, dj) == (0,0): continue
			ni, nj = i+di, j+dj
			if not (0 <= ni < H and 0 <= nj < W): continue
			if M[ni][nj] == '#': continue
			if nd < visited[(ni,nj)]:
				queue.append(((ni,nj), nd))
				visited[(ni,nj)] = nd
print(-1)

Submission status: Accepted

Solution code:
from collections import deque

h, w = map(int, input().split())
ch, cw = map(int, input().split())
dh, dw = map(int, input().split())
slist = [input() for i in range(h)]

if ch == dh and dw == cw:
    print(0)
    exit()

que = deque()
memo_que = deque()
que.append([ch - 1, cw - 1, 0])
memo = [[False for i in range(w)] for j in range(h)]
memo[ch - 1][cw - 1] = True

while len(que) != 0:
    # 幅たん
    while len(que) != 0:
        sh, sw, count = que.popleft()
        memo_que.append([sh, sw, count])
        #print(sh, sw, count)
        for ph, pw in [[-1, 0], [1, 0], [0, 1], [0, -1]]:
            if 0 <= sh + ph < h and 0 <= sw + pw < w:
                if sh + ph == dh - 1 and sw + pw == dw - 1:
                    print(count)
                    exit()
                if memo[ph + sh][pw + sw]:
                    continue
                if slist[sh + ph][sw + pw] == ".":
                    que.append([sh + ph, sw + pw, count])
                    memo[ph + sh][pw + sw] = True
                    memo_que.append([sh + ph, sw + pw, count])

    for sh, sw, count in memo_que:
        #print("w", sh, sw, count)
        for ph in range(-2, 3):
            for pw in range(-2, 3):
                if 0 <= sh + ph < h and 0 <= sw + pw < w:
                    if sh + ph == dh - 1 and sw + pw == dw - 1:
                        print(count + 1)
                        exit()
                    if memo[ph + sh][pw + sw]:
                        continue
                    if slist[sh + ph][sw + pw] == ".":
                        que.append([sh + ph, sw + pw, count + 1])
                        memo[ph + sh][pw + sw] = True
    memo_que.clear()
print(-1)

Submission status: Accepted

Solution code:
#!/usr/bin/env python3
from collections import defaultdict,deque
from heapq import heappush, heappop
from bisect import bisect_left, bisect_right
import sys, random, itertools, math
sys.setrecursionlimit(10**5)
input = sys.stdin.readline
sqrt = math.sqrt
def LI(): return list(map(int, input().split()))
def LF(): return list(map(float, input().split()))
def LI_(): return list(map(lambda x: int(x)-1, input().split()))
def II(): return int(input())
def IF(): return float(input())
def S(): return input().rstrip()
def LS(): return S().split()
def IR(n): return [II() for _ in range(n)]
def LIR(n): return [LI() for _ in range(n)]
def FR(n): return [IF() for _ in range(n)]
def LFR(n): return [LI() for _ in range(n)]
def LIR_(n): return [LI_() for _ in range(n)]
def SR(n): return [S() for _ in range(n)]
def LSR(n): return [LS() for _ in range(n)]
mod = 1000000007
inf = float("INF")

#solve
def solve():
    h, w = LI()
    ch, cw = LI_()
    dh, dw = LI_()
    s = [None] * h
    c = [None] * h
    for i in range(h):
        s[i] = S()
        c[i] = [inf] * w
    q = deque()
    q.append((ch, cw))
    c[ch][cw] = 0
    nq = deque()
    mv = [(0, 1), (1, 0), (-1, 0), (0, -1)]
    mij = [(i, j) for i in range(-2, 3) for j in range(-2, 3)]
    while 1:
        while q:
            nh, nw = q.popleft()
            now = c[nh][nw]
            nq.append((nh, nw))
            for mh, mw in mv:
                mh += nh
                mw += nw
                if 0 <= mh < h and 0 <= mw < w and c[mh][mw] > now and s[mh][mw] == ".":
                    c[mh][mw] = now
                    q.appendleft((mh, mw))
        while nq:
            nh, nw = nq.popleft()
            now = c[nh][nw]
            for mi, mj in mij:
                mi += nh
                mj += nw
                if 0 <= mi < h and 0 <= mj < w and c[mi][mj] > now + 1 and s[mi][mj] == ".":
                    c[mi][mj] = now + 1
                    q.append((mi, mj))
        if len(q) == 0:
            break
    print(-1 if c[dh][dw] == inf else c[dh][dw])
    return


#main
if __name__ == '__main__':
    solve()

Submission status: Accepted

Solution code:
class Grid:
    def __init__(self, H, W, grid, road_wall=(".", "#")):
        self.road, self.wall = road_wall
        self.H = H
        self.W = W
        self.grid = grid
        self.parent = [[-1] * self.W for _ in range(self.H)]
        self.move = [(1, 0), (-1, 0), (0, 1), (0, -1)]     # 動ける場所の候補
        self.move2 = dict()
        self.move2[(1,0)] = [(2,-1),(2,0),(2,1),(2,2),(1,1)]
        self.move2[(-1,0)] = [(-2,-1),(-2,0),(-2,1),(-2,-2),(-1,-1)]
        self.move2[(0,1)] = [(1,2),(0,2),(-1,2),(-2,2),(-1,1)]
        self.move2[(0,-1)] = [(1,-2),(0,-2),(-1,-2),(2,-2),(1,-1)]

    def bfs(self, start=(0,0), goal=-3, time=0, save=False):
        """
        :param start: スタート地点
        :param goal: ゴール地点
        :param save: True = 前回の探索結果を保持する
        :return: （ループがあっても）最短距離。存在しなければ -1
        """
        if save:
            parent = self.parent
        else:
            parent = [[-1] * self.W for _ in range(self.H)]
        p, t = start, time
        parent[p[0]][p[1]] = -2
        next_set = deque([(p, t)])
        broken_set = deque([])
        while next_set:
            while next_set:
                p, t = next_set.popleft()
                h, w = p
                for dh, dw in self.move:
                    nh, nw = (h + dh, w + dw)
                    if nh < 0 or nh >= self.H or nw < 0 or nw >= self.W:
                        continue
                    if parent[nh][nw] != -1:
                        continue
                    if self.grid[nh][nw] == self.wall:         # 壁があったら進まない
                        for dh2, dw2 in self.move2[(dh,dw)]:
                            r = (h + dh2, w + dw2)
                            broken_set.append((r, t))
                        continue
                    if (nh, nw) == goal:
                        return t
                    #### (debug code) ######
                    # self.debug(start, goal, q, t)
                    ########################
                    parent[nh][nw] = p
                    next_set.append(((nh, nw), t))
            while broken_set:
                q, t = broken_set.popleft()
                nh, nw = q
                if nh < 0 or nh >= self.H or nw < 0 or nw >= self.W:
                    continue
                if parent[nh][nw] != -1:
                    continue
                if self.grid[nh][nw] == self.wall:  # 壁があったら進まない
                    continue
                if (nh, nw) == goal:
                    return t + 1
                parent[nh][nw] = 1
                next_set.append((q, t+1))
        return -1

    def debug(self, start, goal, p, t):
        player = p
        debug_grid = list(list(self.grid[h]) for h in range(self.H))
        if start != (None, None):
            debug_grid[start[0]][start[1]] = "S"
        if goal != -3:
            debug_grid[goal[0]][goal[1]] = "G"
        debug_grid[player[0]][player[1]] = "P"
        print("~~~~~~~~~ t = " + str(t + 1) + "  ~~~~~~~~")
        for debug_h in range(self.H):
            print("".join(str(debug_grid[debug_h][debug_w]) for debug_w in range(self.W)))


############################################################################################

from collections import deque
import sys
input = sys.stdin.readline



road, wall = ".", "#"                         # (進行可能を意味する記号, 進行不可を意味する記号)

H, W = map(int,input().split())                # 左上は(h,w)=(0,0)、右下は(h,w)=(H-1,W-1)
x, y = map(int, input().split())
start = (x-1,y-1)
x, y = map(int, input().split())
goal = (x-1,y-1)
grid = []
for h in range(H):
    grid.append(input().rstrip())

g = Grid(H, W, grid, (road, wall))
res = g.bfs(start=start, goal=goal)
print(res)

Submission status: Accepted

Solution code:
from collections import deque


def solve():
    H, W = map(int, input().split())
    C_h, C_w = map(lambda x: int(x) - 1, input().split())
    D_h, D_w = map(lambda x: int(x) - 1, input().split())
    field = [list(input()) for _ in range(H)]
    dp = [[float("inf")] * W for _ in range(H)]
    dp[C_h][C_w] = 0

    q = deque([(C_h, C_w)])
    visited = set()
    while q:
        i, j = q.popleft()
        if (i, j) in visited:
            continue
        visited.add((i, j))
        for di in range(-2, 3):
            for dj in range(-2, 3):
                if (di, dj) == (0, 0):
                    continue
                ni = i + di
                nj = j + dj
                if not (0 <= ni < H and 0 <= nj < W and field[ni][nj] == "."):
                    continue

                if (di, dj) in ((1, 0), (-1, 0), (0, 1), (0, -1)):
                    dp[ni][nj] = min(dp[ni][nj], dp[i][j])
                    q.appendleft((ni, nj))
                else:
                    dp[ni][nj] = min(dp[ni][nj], dp[i][j] + 1)
                    q.append((ni, nj))
    ans = dp[D_h][D_w]
    print(-1) if ans == float("inf") else print(ans)


solve()

Submission status: Accepted

Solution code:
# -*- coding: utf-8 -*-

#############
# Libraries #
#############

import sys
input = sys.stdin.readline

import math
#from math import gcd
import bisect
import heapq
from collections import defaultdict
from collections import deque
from collections import Counter
from functools import lru_cache

#############
# Constants #
#############

MOD = 10**9+7
INF = float('inf')
AZ = "abcdefghijklmnopqrstuvwxyz"

#############
# Functions #
#############

######INPUT######
def I(): return int(input().strip())
def S(): return input().strip()
def IL(): return list(map(int,input().split()))
def SL(): return list(map(str,input().split()))
def ILs(n): return list(int(input()) for _ in range(n))
def SLs(n): return list(input().strip() for _ in range(n))
def ILL(n): return [list(map(int, input().split())) for _ in range(n)]
def SLL(n): return [list(map(str, input().split())) for _ in range(n)]


#####Shorten#####
def DD(arg): return defaultdict(arg)

#####Inverse#####
def inv(n): return pow(n, MOD-2, MOD)

######Combination######
kaijo_memo = []
def kaijo(n):
  if(len(kaijo_memo) > n): return kaijo_memo[n]
  if(len(kaijo_memo) == 0): kaijo_memo.append(1)
  while(len(kaijo_memo) <= n): kaijo_memo.append(kaijo_memo[-1] * len(kaijo_memo) % MOD)
  return kaijo_memo[n]

gyaku_kaijo_memo = []
def gyaku_kaijo(n):
  if(len(gyaku_kaijo_memo) > n): return gyaku_kaijo_memo[n]
  if(len(gyaku_kaijo_memo) == 0): gyaku_kaijo_memo.append(1)
  while(len(gyaku_kaijo_memo) <= n): gyaku_kaijo_memo.append(gyaku_kaijo_memo[-1] * pow(len(gyaku_kaijo_memo),MOD-2,MOD) % MOD)
  return gyaku_kaijo_memo[n]

def nCr(n,r):
  if n == r: return 1
  if n < r or r < 0: return 0
  ret = 1
  ret = ret * kaijo(n) % MOD
  ret = ret * gyaku_kaijo(r) % MOD
  ret = ret * gyaku_kaijo(n-r) % MOD
  return ret

######Factorization######
def factorization(n):
  arr = []
  temp = n
  for i in range(2, int(-(-n**0.5//1))+1):
    if temp%i==0:
      cnt=0
      while temp%i==0: 
        cnt+=1 
        temp //= i
      arr.append([i, cnt])
  if temp!=1: arr.append([temp, 1])
  if arr==[]: arr.append([n, 1])
  return arr

#####MakeDivisors######
def make_divisors(n):
  divisors = []
  for i in range(1, int(n**0.5)+1):
    if n % i == 0:
      divisors.append(i)
      if i != n // i: 
        divisors.append(n//i)
  return divisors

#####MakePrimes######
def make_primes(N):
  max = int(math.sqrt(N))
  seachList = [i for i in range(2,N+1)]
  primeNum = []
  while seachList[0] <= max:
    primeNum.append(seachList[0])
    tmp = seachList[0]
    seachList = [i for i in seachList if i % tmp != 0]
  primeNum.extend(seachList)
  return primeNum

#####GCD#####
def gcd(a, b):
    while b: a, b = b, a % b
    return a

#####LCM#####
def lcm(a, b):
    return a * b // gcd (a, b)

#####BitCount#####
def count_bit(n):
  count = 0
  while n:
    n &= n-1
    count += 1
  return count

#####ChangeBase#####
def base_10_to_n(X, n):
  if X//n: return base_10_to_n(X//n, n)+[X%n]
  return [X%n]

def base_n_to_10(X, n):
  return sum(int(str(X)[-i-1])*n**i for i in range(len(str(X))))

def base_10_to_n_without_0(X, n):
  X -= 1
  if X//n: return base_10_to_n_without_0(X//n, n)+[X%n]
  return [X%n]

#####IntLog#####
def int_log(n, a):
  count = 0
  while n>=a:
    n //= a
    count += 1
  return count

#############
# Main Code #
#############

H,W = IL()
sy,sx = IL()
gy,gx = IL()
data = SLs(H)
      
dx = [0,0,1,-1]
dy = [1,-1,0,0]

ddx = [-2,-1,0,1,2,-2,-1,0,1,2,-2,-1,0,1,2,-2,-1,0,1,2,-2,-1,0,1,2]
ddy = [-2,-2,-2,-2,-2,-1,-1,-1,-1,-1,0,0,0,0,0,1,1,1,1,1,2,2,2,2,2]
 
def bfs(start):
  sy,sx = start
  d = [[INF]*W for i in range(H)]
  d[sy][sx] = 0
  q = deque([start])
  while q:
    y,x = q.popleft()
    for i in range(4):
      ny,nx = y+dy[i], x+dx[i]
      if nx<0 or nx>=W or ny<0 or ny>=H: continue
      if data[ny][nx]=="#" : continue
      if d[ny][nx] <= d[y][x] : continue
      d[ny][nx] = d[y][x]
      q.appendleft((ny,nx))
    for i in range(25):
      ny,nx = y+ddy[i], x+ddx[i]
      if nx<0 or nx>=W or ny<0 or ny>=H: continue
      if data[ny][nx]=="#" : continue
      if d[ny][nx] <= d[y][x] + 1 : continue
      d[ny][nx] = d[y][x] + 1
      q.append((ny,nx))
  return d
 
d = bfs((sy-1,sx-1))

if d[gy-1][gx-1] != INF:
  print(d[gy-1][gx-1])
else:
  print(-1)

Submission status: Accepted

Solution code:
H, W, ch, cw, dh, dw, *S = open(0).read().split()
H, W, ch, cw, dh, dw = [int(_) for _ in [H, W, ch, cw, dh, dw]]
ch -= 1
cw -= 1
dh -= 1
dw -= 1

stack = [[ch, cw]]
dist = [[None] * W for _ in range(H)]
d = 0
while True:
    stack2 = []
    warp = set()
    while stack:
        x, y = stack.pop()
        if (x, y) == (dh, dw):
            print(d)
            exit()
        if dist[x][y] is not None:
            continue
        dist[x][y] = d
        for dx, dy in [[-1, 0], [1, 0], [0, 1], [0, -1]]:
            nx, ny = x + dx, y + dy
            if 0 <= nx < H and 0 <= ny < W and dist[nx][ny] is None:
                if S[nx][ny] == '.':
                    stack += [[nx, ny]]
                else:
                    warp.add((x, y))
    for x, y in warp:
        for dx in range(-2, 3):
            for dy in range(-2, 3):
                nx, ny = x + dx, y + dy
                if 0 <= nx < H and 0 <= ny < W and dist[nx][ny] is None and S[
                        nx][ny] == '.':
                    stack2 += [[nx, ny]]
    if stack2 == []:
        break
    else:
        d += 1
        stack = stack2
print(-1)