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: Time Limit Exceeded

Solution code:
import sys
from collections import deque
readline = sys.stdin.buffer.readline
def even(n): return 1 if n%2==0 else 0

H,W = map(int,readline().split())
sh,sw = map(int,readline().split())
gh,gw = map(int,readline().split())

maze = []
for _ in range(H):
    maze += [list(readline().rstrip().decode())]

maze2 = [[-1]*W for _ in range(H)]

ct = 0
for h in range(H):
    for w in range(W):
        if maze[h][w] == "." and maze2[h][w] == -1:
            y,x = h,w
            maze2[y][x] = ct
            stack = deque([[y,x]])
            while stack:
                i,j = stack.pop()
                for ni,nj in [(0,1),(1,0),(0,-1),(-1,0)]:
                    if not 0 <= i + ni < H or not 0 <= j + nj < W:
                        continue
                    if maze[i+ni][j+nj] == "." and maze2[i+ni][j+nj] == -1:
                        maze2[i+ni][j+nj] = ct
                        stack.append([i+ni,j+nj])
            ct += 1

g = [[] for i in range(ct)]
g2 = [[0]*ct for _ in range(ct)]
for i in range(ct):
    g2[i][i] = 1
for h in range(H):
        for w in range(W):
            if maze2[h][w] != -1:
                for i in range(3):
                    for j in range(-2,3):
                        if not 0 <= i + h < H or not 0 <= j + w < W:
                            continue
                        if maze2[h+i][w+j] != -1 and \
                            not g2[maze2[h][w]][maze2[h+i][w+j]]:
                            g[maze2[h][w]].append((1,maze2[h+i][w+j]))
                            g[maze2[h+i][w+j]].append((1,maze2[h][w]))
                            g2[maze2[h][w]][maze2[h+i][w+j]] = 1
                            g2[maze2[h+i][w+j]][maze2[h][w]] = 1


#ダイクストラ法通常版
#O(ElogV)
import heapq
def dijkstra_heap(s,edge): #s:始点,g:グラフ
    #始点sから各頂点への最短距離
    d = [float("inf")] * len(edge)
    used = [True] * len(edge) #True:未確定
    d[s] = 0
    used[s] = False
    edgelist = []
    for e in edge[s]:
        heapq.heappush(edgelist,e)
    while len(edgelist):
        minedge = heapq.heappop(edgelist)
        #まだ使われてない頂点の中から最小の距離のものを探す
        if not used[minedge[1]]: #既に最小距離が確定しているなら
            continue
        v = minedge[1] #vに頂点を代入
        d[v] = minedge[0] #その頂点のコストに重みを代入
        used[v] = False #vには最小距離が入っていることが証明できる(ヒープキューを使用しているため)
        for e in edge[v]: #頂点vから伸びている辺の先をヒープキューに入れてく
            if used[e[1]]:
                heapq.heappush(edgelist,(e[0]+d[v],e[1]))
    return d #回しきったらreturn(たどり着けなかった頂点はinf.)


start = maze2[sh-1][sw-1]
goal = maze2[gh-1][gw-1]

res = dijkstra_heap(start,g)

if res[goal] == float("inf"):
    print(-1)
else:
    print(res[goal])

Submission status: Time Limit Exceeded

Solution code:
import sys
sys.setrecursionlimit(100000)
h,w=map(int, input().split())

c1, c2 = map(int, input().split())
d1, d2 = map(int, input().split())

data = []
for i in range(h):data.append(input())

ans = []
for i in range(h):ans.append([1000000000]*w)
#print(ans)

def solve(nowx, nowy, length):
    #print(nowx, nowy, length)
    if(ans[nowx][nowy] <= length):return 0
    ans[nowx][nowy] = length
    for i in range(5):
        for j in range(5):
            nextx = nowx+i-2
            nexty = nowy+j-2
            if(nextx < 0 or nextx >= h):continue
            if(nexty < 0 or nexty >= w):continue

            if(data[nextx][nexty] == "."):
                if(abs(i-2)+abs(j-2) <= 1):
                    solve(nextx, nexty, length)

                else:
                    solve(nextx, nexty, length+1)
    return 0

#print(c1, c2)
solve(c1-1, c2-1, 0)

if(ans[d1-1][d2-1] == 1000000000):print(-1)
else:print(ans[d1-1][d2-1])

#print(data[c1-1][c2-1])
#print(data[d1-1][d2-1])

Submission status: Time Limit Exceeded

Solution code:
import collections

h, w = map(int, input().split())
ch, cw = map(int, input().split())
dh, dw = map(int, input().split())
s = []
for i in range(h):
    s.append(input())
num = [[float("inf") for i in range(w)] for i in range(h)]
flag = [[False for i in range(w)] for i in range(h)]
num[ch - 1][cw - 1] = 0
queue = collections.deque([[ch, cw]])
d1 = [[-1, 0], [1, 0], [0, -1], [0, 1]]
d2 = [[-1, -1], [-1, 1], [1, -1], [1, 1], [-2, 0], [2, 0], [0, -2], [0, 2]]
d3 = [[-2, -1], [-1, -2], [2, -1], [1, -2], [-2, 1], [-1, 2], [2, 1], [1, 2]]
d4 = [[-2, -2], [-2, 2], [2, -2], [2, 2]]
while queue:
    test = queue.popleft()
    x = test[0]
    y = test[1]
    flag[y - 1][x - 1] = True
    temp = num[y - 1][x - 1]
    for i in d1:
        x2 = x + i[0]
        y2 = y + i[1]
        if 1 <= x2 <= w and 1 <= y2 <= h and s[y2 - 1][x2 - 1] == "." and flag[y2 - 1][x2 - 1] == False:
            num[y2 - 1][x2 - 1] = temp
            queue.append([x2, y2])
    for i in d2:
        x2 = x + i[0]
        y2 = y + i[1]
        if 1 <= x2 <= w and 1 <= y2 <= h and s[y2 - 1][x2 - 1] == "." and flag[y2 - 1][x2 - 1] == False:
            num[y2 - 1][x2 - 1] = min(temp + 1, num[y2 - 1][x2 - 1])
            queue.append([x2, y2])
    for i in d3:
        x2 = x + i[0]
        y2 = y + i[1]
        if 1 <= x2 <= w and 1 <= y2 <= h and s[y2 - 1][x2 - 1] == "." and flag[y2 - 1][x2 - 1] == False:
            num[y2 - 1][x2 - 1] = min(temp + 1, num[y2 - 1][x2 - 1])
            queue.append([x2, y2])
    for i in d4:
        x2 = x + i[0]
        y2 = y + i[1]
        if 1 <= x2 <= w and 1 <= y2 <= h and s[y2 - 1][x2 - 1] == "." and flag[y2 - 1][x2 - 1] == False:
            num[y2 - 1][x2 - 1] = min(temp + 1, num[y2 - 1][x2 - 1])
            queue.append([x2, y2])
if num[dh - 1][dw - 1] == float("inf"):
    print(-1)
else:
    print(num[dh - 1][dw - 1])

Submission status: Time Limit Exceeded

Solution code:
#!/usr/bin/env python3

import collections
import sys
input=sys.stdin.readline

import heapq

#edgeには[weight,v]を追加していく
def dijkstra(s,edge,n):
    #始点sから各頂点への最短距離
    d = [float("inf")] * n
    used = [True] * n #True:未確定
    d[s] = 0
    used[s] = False
    edgelist = []
    for e in edge[s]:
        heapq.heappush(edgelist,e)
    while len(edgelist):
        minedge = heapq.heappop(edgelist)
        #まだ使われてない頂点の中から最小の距離のものを探す
        if not used[minedge[1]]:
            continue
        v = minedge[1]
        d[v] = minedge[0]
        used[v] = False
        for e in edge[v]:
            if used[e[1]]:
                heapq.heappush(edgelist,[e[0]+d[v],e[1]])
    return d

class UnionFind():
  def __init__(self,n):
    self.n=n
    self.root=[-1]*(n+1)
    self.rank=[0]*(n+1)
  def FindRoot(self,x):
    if self.root[x]<0:
      return x
    else:
      self.root[x]=self.FindRoot(self.root[x])
      return self.root[x]
  def Unite(self,x,y):
    x=self.FindRoot(x)
    y=self.FindRoot(y)
    if x==y:
      return
    else:
      if self.rank[x]>self.rank[y]:
        self.root[x]+=self.root[y]
        self.root[y]=x
      elif self.rank[x]<=self.rank[y]:
        self.root[y]+=self.root[x]
        self.root[x]=y
        if self.rank[x]==self.rank[y]:
          self.rank[y]+=1
  def isSameGroup(self,x,y):
    return self.FindRoot(x)==self.FindRoot(y)
  def Count(self,x):
    return -self.root[self.FindRoot(x)]

h,w=map(int,input().split())
sy,sx=map(int,input().split())
gy,gx=map(int,input().split())
board=''
for _ in range(h):
    board+=input().replace('\n','')
uf=UnionFind(h*w)
for y in range(h):
    for x in range(w):
        v=y*w+x
        if board[v]=='#':
            continue
        if y-1>=0 and board[v-w]=='.':
            uf.Unite(v,v-w)
        if y+1<h and board[v+w]=='.':
            uf.Unite(v,v+w)
        if x-1>=0 and board[v-1]=='.':
            uf.Unite(v,v-1)
        if x+1<w and board[v+1]=='.':
            uf.Unite(v,v+1)
edges=[[] for _ in range(h*w+1)]
checked=set()
for y in range(h):
    for x in range(w):
        if board[y*w+x]=='#':
            continue
        for dy in [-2,-1,0,1,2]:
            if y+dy<0 or y+dy>=h:
                continue
            for dx in [-2,-1,0,1,2]:
                if x+dx<0 or x+dx>=w:
                    continue
                if board[(y+dy)*w+(x+dx)]=='#':
                    continue
                r1=uf.FindRoot(y*w+x)
                r2=uf.FindRoot((y+dy)*w+x+dx)
                if (r1,r2) in checked:
                    continue
                if r1!=r2:
                    edges[r1].append([1,r2])
                    checked.add((r1,r2))
dist=dijkstra(uf.FindRoot((sy-1)*w+(sx-1)),edges,h*w)
ans=dist[uf.FindRoot((gy-1)*w+(gx-1))]
if ans==float('inf'):
    print(-1)
else:
    print(ans)

Submission status: Time Limit Exceeded

Solution code:
H, W = map(int, input().split())
sh, sw = map(int, input().split())
gh, gw = map(int, input().split())

sh += 1
sw += 1
gh += 1
gw += 1

S = [0]*(H+4)
S[0] = '*'*(W+4)
S[1] = '*'*(W+4)
S[-2] = '*'*(W+4)
S[-1] = '*'*(W+4)
for h in range(2,H+2):
  S[h] = '**' + input() + '**'

visited = [10**7]*((W+4)*(H+4))
dh1 = [0,1,0,-1]
dw1 = [1,0,-1,0]
dh2 = [2,2,2,2,2,1,1,1,1,0,0,-1,-1,-1,-1,-2,-2,-2,-2,-2]
dw2 = [-2,-1,0,1,2,-2,-1,1,2,-2,2,-2,-1,1,2,-2,-1,0,1,2]

from collections import deque
d = deque()
visited[sh*(W+4)+sw] = 0
d.append(sh*(W+4)+sw)

while len(d)>0:
  a = d.popleft()
  h,w = divmod(a,W+4)
  cnt = visited[a]
  for i in range(4):
    h1 = h+dh1[i]
    w1 = w+dw1[i]
    a1 = h1*(W+4)+w1
    if S[h1][w1]=='.':
      if visited[a1]>cnt:
        visited[a1]=cnt
        d.append(a1)
  for i in range(20):
    h2 = h+dh2[i]
    w2 = w+dw2[i]
    a2 = h2*(W+4)+w2
    if S[h2][w2]=='.':
      if visited[a2]>cnt+1:
        visited[a2]=cnt+1
        d.append(a2)
ans = visited[gh*(W+4)+gw] if visited[gh*(W+4)+gw]<10**7 else -1
print(ans)

Submission status: Time Limit Exceeded

Solution code:
import sys

sys.setrecursionlimit(1000000)

def main():
    H, W = map(int, input().split())
    ch, cw = map(int, input().split())
    dh, dw = map(int, input().split())
    S = [0] * H
    for i in range(H):
        S[i] = list(input().split()[0])

    res_map = [[-1] * W for i in range(H)]
    res_map[ch-1][cw-1] = 0

    def dfs(xi, yi):
        cost = res_map[xi][yi]
        for (dx, dy) in [(1,0), (-1,0), (0,1), (0,-1)]:
                x = xi + dx
                y = yi + dy
                if 0 <= x and x < H and 0 <= y and y < W:
                    if S[x][y] == "." and (res_map[x][y] > cost or res_map[x][y] == -1):
                        res_map[x][y] = cost
                        dfs(x,y)

        for dx in range(-2,3):
            for dy in range(-2,3):
                x = xi + dx
                y = yi + dy
                if 0 <= x and x < H and 0 <= y and y < W:
                    if S[x][y] == "." and (res_map[x][y] > cost+1 or res_map[x][y] == -1):
                        res_map[x][y] = cost+1
                        dfs(x,y)

    dfs(ch-1, cw-1)
    print(res_map[dh-1][dw-1])

if __name__ == "__main__":
    main()

Submission status: Time Limit Exceeded

Solution code:
from heapq import heappush, heappop
from itertools import product

H, W = map(int, input().split())
start = tuple(map(lambda x: int(x) - 1, input().split()))
goal = tuple(map(lambda x: int(x) - 1, input().split()))

maze = []
for _ in range(H):
    maze.append(list(input()))

serve = set()
visited = set()

Q = [(0, start)]
while Q:
    c, pos = heappop(Q)
    visited.add(pos)
    if pos == goal:
        print(c)
        exit()
    # A
    for move in ((0, 1), (1, 0), (-1, 0), (0, -1)):
        nx = pos[0] + move[0]
        ny = pos[1] + move[1]
        if 0 <= nx < H and 0 <= ny < W:
            if maze[nx][ny] == '.':
                if (nx, ny) not in visited:
                    heappush(Q, (c, (nx, ny)))
    # B
    for move in product(range(-2, 3), repeat=2):
        nx = pos[0] + move[0]
        ny = pos[1] + move[1]
        if 0 <= nx < H and 0 <= ny < W:
            if maze[nx][ny] == '.':
                if (nx, ny) not in serve & visited:
                    heappush(Q, (c + 1, (nx, ny)))
                    serve.add((nx, ny))
print(-1)

Submission status: Time Limit Exceeded

Solution code:
h,w=map(int,input().split())
nx,ny=map(int,input().split())
gx,gy=map(int,input().split())
maze=[input()for i in range(h)]
from heapq import heapify, heappop, heappush
seen=set()
gx-=1;gy-=1

hq=[(0,nx-1,ny-1)]
while hq:
    c,x,y=heappop(hq)
    if w*x +y in seen:continue
    seen.add(w*x +y)
    if x==gx and y==gy:print(c);exit()
    if x and w*(x-1)+y not in seen and maze[x-1 ][y]!="#":
        heappush(hq,(c,x-1,y))
    if y and w*x+y-1 not in seen and maze[x][y-1]!="#":
        heappush(hq,(c,x,y-1))
    if x+1<h  and w*(x+1)+y not in seen and maze[x+1][y]!="#":
        heappush(hq,(c,x+1,y))
    if y+1<w  and w*x+y+1 not in seen and maze[x][y+1]!="#":
        heappush(hq,(c,x,y+1))
    for i in range(max(0,x-2),min(h,x+3)):
        for j in range(max(0,y-2),min(w,y+3)):
            if i==x and j==y:continue
            if maze[i][j]=="."and w*i + j not in seen:
                heappush(hq,(c+1,i,j))

print(-1)

Submission status: Time Limit Exceeded

Solution code:
def resolve():
    '''
    code here
    '''
    import collections

    H, W = [int(item) for item in input().split()]
    Ch, Cw = [int(item)-1 for item in input().split()]
    Dh, Dw = [int(item)-1 for item in input().split()]
    grid = [[item for item in input()] for _ in range(H)]

    fp = [[10**6 for _ in range(W)] for _ in range(H)]

    que = collections.deque([[Ch, Cw, 0]])
    fp[Ch][Cw] = 0
    next_y_x = [[0, 1], [1, 0], [-1, 0], [0, -1]]
    w_goto = []
    for i in range(5):
        for j in range(5):
            w_goto.append([-2 + i, -2 + j])

    is_found = False

    while que:
        temp = que.popleft()
        w_num = temp[2]

        for dy, dx in next_y_x:
            ny = temp[0] + dy
            nx = temp[1] + dx

            if 0 <= ny <= H-1 and 0 <= nx <= W-1:
                if grid[ny][nx] == '.' and fp[ny][nx] > w_num:
                    que.append([ny, nx, temp[2]])
                    fp[ny][nx] = w_num
        
        for dy, dx in w_goto:
            ny = temp[0] + dy
            nx = temp[1] + dx
            nw = w_num +1

            if 0 <= ny <= H-1 and 0 <= nx <= W-1:
                if grid[ny][nx] == '.' and fp[ny][nx] > w_num:
                    que.append([ny, nx, nw])
                    fp[ny][nx] = nw

    if fp[Dh][Dw] != 10**6:
        print(fp[Dh][Dw])
    else:
        print(-1)

if __name__ == "__main__":
    resolve()

Submission status: Time Limit Exceeded

Solution code:
from collections import deque
H, W = map(int, input().split())
cy, cx = map(int, input().split())
dy, dx = map(int, input().split())
cy -= 1
cx -= 1
dy -= 1
dx -= 1

S = [list(input().strip()) for _ in range(H)]

worps = [[float('inf')]*W for _ in range(H)]
used = [[False]*W for _ in range(H)]
q = deque([[cy, cx]])

worp = 0
while q:
    v = {}
    while q:
        y, x = q.popleft()
        used[y][x] = True
        worps[y][x] = min(worps[y][x], worp)

        for h in range(-2+y, 3+y):
            for w in range(-2+x, 3+x):
                if 0 <= h and h < H and 0 <= w and w < W and S[h][w] == "." and not used[h][w]:
                    v[(h, w)] = True

        for h, w in [[0, 1], [0, -1], [1, 0], [-1, 0]]:
            ny, nx = y+h, x+w
            if 0 <= ny and ny < H and 0 <= nx and nx < W:
                if not used[ny][nx] and S[ny][nx] == ".":
                    q.append([ny, nx])

    worp += 1
    for h, w in v.keys():
        if not used[h][w]:
            q.append([h, w])
            used[h][w] = True

ans = worps[dy][dx]
if ans != float('inf'):
    print(ans)
else:
    print(-1)

Submission status: Time Limit Exceeded

Solution code:
def is_sosed(h1, w1):
    if h1 > 0:
        if (dp[h1-1][w1] == -1):
            if (m[h1-1][w1] == '.'):
                dp[h1-1][w1] = dp[h1][w1]
                is_sosed(h1-1, w1)
            else:
                dp[h1-1][w1] = 1000000000
    if w1 > 0:
        if (dp[h1][w1-1] == -1):
            if (m[h1][w1-1] == '.'):
                dp[h1][w1-1] = dp[h1][w1]
                is_sosed(h1, w1-1)
            else:
                dp[h1][w1-1] = 1000000000
    if h1 < h - 1:
        if (dp[h1+1][w1] == -1):
            if (m[h1+1][w1] == '.'):
                dp[h1+1][w1] = dp[h1][w1]
                is_sosed(h1+1, w1)
            else:
                dp[h1+1][w1] = 1000000000
    if w1 < w - 1:
        if (dp[h1][w1+1] == -1):
            if (m[h1][w1+1] == '.'):
                dp[h1][w1+1] = dp[h1][w1]
                is_sosed(h1, w1+1)
            else:
                dp[h1][w1+1] = 1000000000

def find_warps(now):
    fl = True
    for i in range(h):
        for j in range(w):
            if dp[i][j] == now:
                for k in range(max(0, i-2), min(h, i+3)):
                    for p in range(max(0, j-2), min(w, j+3)):
                        if dp[k][p] == -1:
                            if m[k][p] == '.':
                                fl = False
                                dp[k][p] = dp[i][j] + 1
                                stack.append([k, p])
                            else:
                                dp[k][p] = 1000000000
    return fl

h, w = map(int, input().split())
ch, cw = map(int, input().split())
dh, dw = map(int, input().split())
m = [[] for i in range(h)]
dp = [[-1]*w for i in range(h)]
for i in range(h):
    m[i] = input()
dp[ch-1][cw-1] = 0
stack = [[ch-1, cw-1]]
now = 0
fl = False
while dp[dh-1][dw-1] == -1:
    while stack:
        h11, w11 = stack.pop()
        is_sosed(h11, w11)
    fl = find_warps(now)
    now += 1
    if fl:
        break
print(dp[dh-1][dw-1])

Submission status: Time Limit Exceeded

Solution code:
from sys import stdin
from collections import deque
input = stdin.readline

H, W = map(int, input().split())
ch, cw = map(int, input().split())
dh, dw = map(int, input().split())
S = [list(input().rstrip()) for _ in range(H)]

dir_h = [0, 0, 1, -1]
dir_w = [1, -1, 0, 0]

seen = [[-1 for _ in range(W)] for _ in range(H)]
edge = []
nex = [[ch - 1, cw - 1]]
num = 0


def bfs():
    q = deque([])

    for h, w in nex:
        q.append([h, w])
        seen[h][w] = num
        while q:
            h, w = q.popleft()

            for dh, dw in zip(dir_h, dir_w):
                nh, nw = h + dh, w + dw

                if nh < 0 or nh >= H or nw < 0 or nw >= W:
                    continue
                elif S[nh][nw] == "#":
                    edge.append([h, w])
                    continue
                elif seen[nh][nw] != -1:
                    continue
                else:
                    seen[nh][nw] = num
                    q.append([nh, nw])


def dfs():
    d = deque([])
    for h, w in edge:
        d.append([h, w])

        while d:
            h, w = d.pop()
            num = seen[h][w]
            for dh in range(-2, 3):
                for dw in range(-2, 3):
                    nh, nw = h + dh, w + dw

                    if nh < 0 or nh >= H or nw < 0 or nw >= W:
                        continue
                    elif S[nh][nw] == "#":
                        continue
                    elif seen[nh][nw] != -1:
                        continue
                    else:
                        seen[nh][nw] = min(num, seen[nh][nw])
                        nex.append([nh, nw])


while True:
    bfs()
    nex = []
    num += 1
    dfs()
    if not edge:
        break
    edge = []

# for s in seen:
#     print(s)

print(seen[dh - 1][dw - 1])

Submission status: Time Limit Exceeded

Solution code:
#abc176-d
import sys,math,collections,itertools
input = sys.stdin.readline

H,W=list(map(int,input().split()))
Ch,Cw=list(map(int,input().split()))
Dh,Dw=list(map(int,input().split()))
s=[ input().rstrip() for _ in range(H)]

#DPで遷移が2種類　初期値をinf として、現在値より小さければ遷移可能とする
dp = [ [float('inf') ]*W  for _ in range(H)]

q = collections.deque([])
q.append((Ch-1,Cw-1))
dp[Ch-1][Cw-1]=0
while q:
    nh,nw = q.popleft()
    #徒歩での遷移
    if nh>0 and s[nh-1][nw] =='.' and dp[nh-1][nw]>dp[nh][nw]:
        q.append((nh-1,nw))
        dp[nh-1][nw] = dp[nh][nw]
    if nh<H-1 and s[nh+1][nw] =='.' and dp[nh+1][nw]>dp[nh][nw]:
        q.append((nh+1,nw))
        dp[nh+1][nw] = dp[nh][nw]
    if nw>0 and s[nh][nw-1] =='.' and dp[nh][nw-1]>dp[nh][nw]:
        q.append((nh,nw-1))
        dp[nh][nw-1] = dp[nh][nw]
    if nw<W-1 and s[nh][nw+1] =='.' and dp[nh][nw+1]>dp[nh][nw]:
        q.append((nh,nw+1))
        dp[nh][nw+1] = dp[nh][nw]
    #ワープで遷移
    for ih in range(-2,3,1):
        for iw in range(-2,3,1):
            if (0<= nh+ih<=H-1) and (0<=nw+iw<=W-1):
                if s[nh+ih][nw+iw] =='.' and dp[nh+ih][nw+iw]>dp[nh][nw]:
                    q.append((nh+ih,nw+iw))
                    dp[nh+ih][nw+iw] = dp[nh][nw]+1


ans = dp[Dh-1][Dw-1]
print(-1 if ans==float('inf') else ans)

Submission status: Time Limit Exceeded

Solution code:
H,W = map(int, input().split())
Ch,Cw = map(int, input().split())
Dh,Dw = map(int, input().split())

Ch += 1
Cw += 1
Dh += 1
Dw += 1

S = [["#" for _ in range(W + 4)] for _ in range(2)]
for _ in range(H):
    S.append(["#"] * 2 + list(input()) + ["#"] * 2)
S.append(["#" for _ in range(W + 4)])
S.append(["#" for _ in range(W + 4)])

cnt = [[float("inf")] * (W + 4) for _ in range(H + 4)]
cnt[Ch][Cw] = 0

DX = [0, 0, -1, 1]
DY = [-1, 1, 0, 0]

from collections import deque

def serch(Sh, Sw, count):
    q = [(Sh, Sw)]
    done = [(Sh, Sw)]
    while q:
        qq = []
        for h, w in q:
            for dy, dx in zip(DY, DX):
                nh = h + dy
                nw = w + dx

                if S[nh][nw] == "." and cnt[nh][nw] > count:
                    qq.append((nh, nw))
                    done.append((nh, nw))
                    cnt[nh][nw] = count
        q = qq
    
    return done

DONE = serch(Ch, Cw, 0)
ans = 1
while DONE:
    DDONE = []
    for h, w in DONE:
        for dy in range(-2, 3):
            for dx in range(-2, 3):
                nh = h + dy
                nw = w + dx

                if S[nh][nw] == "." and cnt[nh][nw] > ans:
                    cnt[nh][nw] = ans
                    DDONE += serch(nh, nw, ans)
    
    ans += 1
    DONE = DDONE

if cnt[Dh][Dw] == float("inf"):
    print(-1)
else:
    print(cnt[Dh][Dw])

Submission status: Time Limit Exceeded

Solution code:
import sys, io, os, re
from bisect import bisect, bisect_left, bisect_right, insort, insort_left, insort_right
from pprint import pprint
from math import sin, cos, pi, radians, sqrt, floor, ceil
from copy import copy, deepcopy
from collections import deque
from fractions import gcd
from functools import reduce
from itertools import groupby
from heapq import heapify, heappush, heappop

# sys.setrecursionlimit(5000)

n1 = lambda: int(sys.stdin.readline().strip())
nn = lambda: list(map(int, sys.stdin.readline().strip().split()))
f1 = lambda: float(sys.stdin.readline().strip())
fn = lambda: list(map(float, sys.stdin.readline().strip().split()))
s1 = lambda: sys.stdin.readline().strip()
sn = lambda: list(sys.stdin.readline().strip().split())
nl = lambda n: [n1() for _ in range(n)]
fl = lambda n: [f1() for _ in range(n)]
sl = lambda n: [s1() for _ in range(n)]
nm = lambda n: [nn() for _ in range(n)]
fm = lambda n: [fn() for _ in range(n)]
sm = lambda n: [sn() for _ in range(n)]

def array1(n, d=0): return [d] * n
def array2(n, m, d=0): return [[d] * m for x in range(n)]
def array3(n, m, l, d=0): return [[[d] * l for y in xrange(m)] for x in xrange(n)]
def linc(A, d=1): return map(lambda x: x + d, A)
def ldec(A, d=1): return map(lambda x: x - d, A)

H, W = nn()
Ch, Cw = nn()
Dh, Dw = nn()
S = sm(H)

T = [u"#"*(W+4)] * 2
for s in S:
    T.append("##" + s[0] + "##")
T += [u"#"*(W+4)] * 2

H += 4
W += 4
Ch += 2 - 1
Cw += 2 - 1
Dh += 2 - 1
Dw += 2 - 1

deq1 = deque()
deq1.append((Ch, Cw))
deq2 = deque()

cnt = 0

memo = array2(H, W, 10**6)
memo[Ch][Cw] = 0

for i in range(10**6):
    #pprint(T)
    #pprint(memo)
    #print("-"*30 + "\n")

    if len(deq1) == 0:
        print(-1)
        exit(0)

    while len(deq1) > 0:
        h, w = deq1.pop()

        if h == Dh and w == Dw:
            print(i)
            exit(0)

        def sch(x, y, i):
            #print(x, y, T[x][y])
            if T[x][y] == "." and i < memo[x][y]:
                memo[x][y] = i
                deq1.append((x, y))

        sch(h+1, w, i)
        sch(h-1, w, i)
        sch(h, w+1, i)
        sch(h, w-1, i)

    for j in range(H):
        for k in range(W):
            if memo[j][k] == i:
                for l in range(-2, 3):
                    for m in range(-2, 3):
                        if T[j+l][k+m] == "." and i + 1 < memo[j+l][k+m]:
                            memo[j+l][k+m] = i + 1
                            deq2.append((j+l, k+m))

    deq1 = deq2
    deq2 = deque()

Submission status: Time Limit Exceeded

Solution code:
from collections import deque
import sys

def input():
    return sys.stdin.readline().strip()

def main():
    H,W = map(int,input().split())
    Ch,Cw = map(int,input().split())
    Dh,Dw = map(int,input().split())
    S = [list(input()) for _ in range(H)]
    S[Ch-1][Cw-1] = 0

    def bfs(x,y):
        que = deque()
        que.append((x,y))

        while que:
            x,y = que.popleft()
            for dx in range(-2,3):
                for dy in range(-2,3):
                    sx = x + dx
                    sy = y + dy
                    if sx < 0 or sx >= W or sy < 0 or sy >= H:
                        continue
                    if S[sy][sx] == '#':
                        continue
                    if S[sy][sx] == '.' and (dx,dy) in ((-1,0),(1,0),(0,-1),(0,1)):
                        que.append((sx,sy))
                        S[sy][sx] = S[y][x]
                    elif S[sy][sx] == '.' and (dx,dy) not in ((-1,0),(1,0),(0,-1),(0,1)):
                        que.append((sx,sy))
                        S[sy][sx] = S[y][x] + 1
                    elif (dx,dy) in ((-1,0),(1,0),(0,-1),(0,1)):
                        if S[sy][sx] > S[y][x]:
                            S[sy][sx] = S[y][x]
                            que.append((sx,sy))
                    else:
                        if S[sy][sx] > S[y][x] + 1:
                            S[sy][sx] = S[y][x] + 1
                            que.append((sx,sy))
    bfs(Cw-1,Ch-1)
    print(S[Dh-1][Dw-1] if S[Dh-1][Dw-1] != '.' else '-1')

if __name__ == "__main__":
    main()