Buggy python submission (verdict: Time Limit Exceeded):
def f_pond_skater(INF=float('inf')):
    from fractions import Fraction
    from math import ceil
    from collections import deque
    H, W, K = [int(i) for i in input().split()]
    start_row, start_col, target_row, target_col = [int(i) - 1 for i in input().split()]
    Grid = [input() for _ in range(H)]

    def is_inside(row, col):
        return (0 <= row < H) and (0 <= col < W)

    # dist[row][col][dir]: スタートから出発してマス (row, col) で
    # 方向 dir を向くまでに要する最小コスト (3 次元配列を 1 次元配列にしている)
    dist = [INF] * (H * W * 4)
    dr, dc = (0, -1, 0, 1), (-1, 0, 1, 0)  # '0123' と '左上右下' を対応

    def to_id(row, col, direction):
        return (row * W + col) * 4 + direction

    queue = deque([(0, start_row, start_col, 0)])
    while queue:
        cost, row, col, direction = queue.pop()
        current_id = to_id(row, col, direction)
        dist[current_id] = cost

        # 1マス直進する
        nr, nc = row + dr[direction], col + dc[direction]
        move_id = to_id(nr, nc, direction)
        if (is_inside(nr, nc) and Grid[nr][nc] == '.' and
                dist[move_id] > cost + Fraction(1, K)):
            queue.appendleft((cost + Fraction(1, K), nr, nc, direction))

        # 向きを 90 度変える
        for i in (1, 3):
            rot_id = to_id(row, col, (direction + i) % 4)
            new_cost = ceil(float(cost))
            if dist[rot_id] > new_cost:
                queue.appendleft((new_cost, row, col, (direction + i) % 4))

    ans = min(dist[to_id(target_row, target_col, d)] for d in range(4))
    return ceil(float(ans)) if ans != float('inf') else -1

print(f_pond_skater())

Fixed submission:
def f_pond_skater():
    from heapq import heappush, heappop
    H, W, K = [int(i) for i in input().split()]
    start_row, start_col, target_row, target_col = [int(i) - 1 for i in input().split()]
    Grid = [input() for _ in range(H)]

    heap = []
    dist = [[float('inf')] * W for _ in range(H)]
    dist[start_row][start_col] = 0

    diff = ((0, 1), (1, 0), (0, -1), (-1, 0))
    heappush(heap, (0, start_row, start_col))
    while heap:
        cost, row, col = heappop(heap)
        cost_next = cost + 1

        if row == target_row and col == target_col:
            return cost

        for dr, dc in diff:
            nr, nc = row, col
            for _ in range(K):
                nr += dr
                nc += dc
                if not (0 <= nr < H and 0 <= nc < W) or Grid[nr][nc] == '@':
                    break
                if dist[nr][nc] > cost_next:
                    dist[nr][nc] = cost_next
                    heappush(heap, (cost_next, nr, nc))
                elif dist[nr][nc] == cost_next:
                    continue
                else:
                    break
    return -1

print(f_pond_skater())

Buggy python submission (verdict: Time Limit Exceeded):
def f_pond_skater():
    from fractions import Fraction
    from math import ceil
    from collections import deque
    H, W, K = [int(i) for i in input().split()]
    start_row, start_col, target_row, target_col = [int(i) - 1 for i in input().split()]
    Grid = [input() for _ in range(H)]

    def is_inside(row, col):
        return (0 <= row < H) and (0 <= col < W)

    dp = [[[float('inf')] * 4 for j in range(W)] for i in range(H)]
    dr, dc = (0, -1, 0, 1), (-1, 0, 1, 0)  # '0123' と '左上右下' を対応
    queue = deque([(0, start_row, start_col, 0)])
    while queue:
        cost, row, col, direction = queue.pop()
        dp[row][col][direction] = cost

        # 1マス直進する
        nr, nc = row + dr[direction], col + dc[direction]
        if (is_inside(nr, nc) and Grid[nr][nc] == '.' and
                dp[nr][nc][direction] > cost + Fraction(1, K)):
            queue.appendleft((dp[row][col][direction] + Fraction(1, K), nr, nc, direction))

        # 向きを 90 度変える
        for i in (1, 3):
            if dp[row][col][(direction + i) % 4] > ceil(float(cost)):
                queue.appendleft((ceil(float(cost)), row, col, (direction + i) % 4))

    ans = min(dp[target_row][target_col][d] for d in range(4))
    return ceil(float(ans)) if ans != float('inf') else -1

print(f_pond_skater())

Fixed submission:
def f_pond_skater():
    from heapq import heappush, heappop
    H, W, K = [int(i) for i in input().split()]
    start_row, start_col, target_row, target_col = [int(i) - 1 for i in input().split()]
    Grid = [input() for _ in range(H)]

    heap = []
    dist = [[float('inf')] * W for _ in range(H)]
    dist[start_row][start_col] = 0

    diff = ((0, 1), (1, 0), (0, -1), (-1, 0))
    heappush(heap, (0, start_row, start_col))
    while heap:
        cost, row, col = heappop(heap)
        cost_next = cost + 1

        if row == target_row and col == target_col:
            return cost

        for dr, dc in diff:
            nr, nc = row, col
            for _ in range(K):
                nr += dr
                nc += dc
                if not (0 <= nr < H and 0 <= nc < W) or Grid[nr][nc] == '@':
                    break
                if dist[nr][nc] > cost_next:
                    dist[nr][nc] = cost_next
                    heappush(heap, (cost_next, nr, nc))
                elif dist[nr][nc] == cost_next:
                    continue
                else:
                    break
    return -1

print(f_pond_skater())

Buggy python submission (verdict: Time Limit Exceeded):
def f_pond_skater():
    from fractions import Fraction
    from heapq import heappop, heappush
    from math import ceil
    H, W, K = [int(i) for i in input().split()]
    start_row, start_col, target_row, target_col = [int(i) - 1 for i in input().split()]
    Grid = [input() for _ in range(H)]

    def is_inside(row, col):
        return (0 <= row < H) and (0 <= col < W)

    dp = [[[float('inf')] * 4 for j in range(W)] for i in range(H)]
    dr, dc = (0, -1, 0, 1), (-1, 0, 1, 0)  # '0123' と '左上右下' を対応
    queue = [(0, start_row, start_col, i) for i in range(4)]
    while queue:
        cost, row, col, direction = heappop(queue)
        dp[row][col][direction] = cost

        # 1マス直進する
        nr, nc = row + dr[direction], col + dc[direction]
        if (is_inside(nr, nc) and Grid[nr][nc] == '.' and
                dp[nr][nc][direction] > cost + Fraction(1, K)):
            heappush(queue, (dp[row][col][direction] + Fraction(1, K), nr, nc, direction))

        # 向きを 90 度変える
        for i in (1, 3):
            if dp[row][col][(direction + i) % 4] > ceil(float(cost)):
                heappush(queue, (ceil(float(cost)), row, col, (direction + i) % 4))

    ans = min(dp[target_row][target_col][d] for d in range(4))
    return ceil(float(ans)) if ans != float('inf') else -1

print(f_pond_skater())


Fixed submission:
def f_pond_skater():
    from heapq import heappush, heappop
    H, W, K = [int(i) for i in input().split()]
    start_row, start_col, target_row, target_col = [int(i) - 1 for i in input().split()]
    Grid = [input() for _ in range(H)]

    heap = []
    dist = [[float('inf')] * W for _ in range(H)]
    dist[start_row][start_col] = 0

    diff = ((0, 1), (1, 0), (0, -1), (-1, 0))
    heappush(heap, (0, start_row, start_col))
    while heap:
        cost, row, col = heappop(heap)
        cost_next = cost + 1

        if row == target_row and col == target_col:
            return cost

        for dr, dc in diff:
            nr, nc = row, col
            for _ in range(K):
                nr += dr
                nc += dc
                if not (0 <= nr < H and 0 <= nc < W) or Grid[nr][nc] == '@':
                    break
                if dist[nr][nc] > cost_next:
                    dist[nr][nc] = cost_next
                    heappush(heap, (cost_next, nr, nc))
                elif dist[nr][nc] == cost_next:
                    continue
                else:
                    break
    return -1

print(f_pond_skater())

Buggy python submission (verdict: Time Limit Exceeded):
def f_pond_skater():
    from fractions import Fraction
    from heapq import heappop, heappush
    from math import ceil
    H, W, K = [int(i) for i in input().split()]
    start_row, start_col, target_row, target_col = [int(i) - 1 for i in input().split()]
    Grid = [input() for _ in range(H)]

    def is_inside(row, col):
        return (0 <= row < H) and (0 <= col < W)

    dp = [[[float('inf')] * 4 for j in range(W)] for i in range(H)]
    dr, dc = (0, -1, 0, 1), (-1, 0, 1, 0)  # '0123' と '左上右下' を対応
    queue = [(0, start_row, start_col, i) for i in range(4)]
    while queue:
        cost, row, col, direction = heappop(queue)
        dp[row][col][direction] = cost

        # 1マス直進する
        nr, nc = row + dr[direction], col + dc[direction]
        if (is_inside(nr, nc) and Grid[nr][nc] == '.' and
                dp[nr][nc][direction] > cost + Fraction(1, K)):
            heappush(queue, (dp[row][col][direction] + Fraction(1, K), nr, nc, direction))

        # 向きを 90 度変える
        for i in (1, 3):
            if dp[row][col][(direction + i) % 4] > ceil(float(cost)):
                heappush(queue, (ceil(float(cost)), row, col, (direction + i) % 4))

    ans = min(dp[target_row][target_col][d] for d in range(4))
    return ceil(float(ans)) if ans != float('inf') else -1

print(f_pond_skater())

Fixed submission:
def f_pond_skater():
    from heapq import heappush, heappop
    H, W, K = [int(i) for i in input().split()]
    start_row, start_col, target_row, target_col = [int(i) - 1 for i in input().split()]
    Grid = [input() for _ in range(H)]

    heap = []
    dist = [[float('inf')] * W for _ in range(H)]
    dist[start_row][start_col] = 0

    diff = ((0, 1), (1, 0), (0, -1), (-1, 0))
    heappush(heap, (0, start_row, start_col))
    while heap:
        cost, row, col = heappop(heap)
        cost_next = cost + 1

        if row == target_row and col == target_col:
            return cost

        for dr, dc in diff:
            nr, nc = row, col
            for _ in range(K):
                nr += dr
                nc += dc
                if not (0 <= nr < H and 0 <= nc < W) or Grid[nr][nc] == '@':
                    break
                if dist[nr][nc] > cost_next:
                    dist[nr][nc] = cost_next
                    heappush(heap, (cost_next, nr, nc))
                elif dist[nr][nc] == cost_next:
                    continue
                else:
                    break
    return -1

print(f_pond_skater())