Buggy python submission (verdict: Time Limit Exceeded):

class Game:
    def __init__(self, mp, h, w, k):
        self.mp = mp
        self.H = h
        self.W = w

        self.K = k
        self.score = 0
        self.erase_flag = False
        self.cnt = 0
        
    def erase(self):
        tot = 0
        for y in range(self.H):
            line = self.mp[y]
            new_line, add_score = self.fix(line)
            self.mp[y] = new_line
            tot += add_score
            if add_score != 0:
                self.erase_flag = True
        if self.erase_flag:
            self.score += tot*pow(2, self.cnt)
            self.cnt += 1
    
    def fix(self, line):
        add_score = 0
        new_line = line
        for length in range(self.W, self.K-1, -1):
            for left in range(self.W - length+1):
                if all(map(lambda x:x==new_line[left], new_line[left:left+length])):
                    add_score += new_line[left]*length
                    new_line = new_line[:left] + [0]*length + new_line[left+length:]
                    # 最後の要素まで見たか？
                    # if self.W == left+length:
                    #     return new_line, add_score
        return new_line, add_score
    
    def fall(self):
        for x in range(self.W):
            col = [self.mp[y][x] for y in range(self.H) if self.mp[y][x] != 0]
            # for y in range(self.H):
            #     if self.mp[y][x] != 0:
            #         col.append(self.mp[y][x])
            col = [0]*(self.H - len(col)) + col
            for y in range(self.H):
                self.mp[y][x] = col[y]


    def run(self):
        while True:
            self.erase_flag = False
            self.erase()
            if not self.erase_flag:
                break
            self.fall()

import sys
sys.setrecursionlimit(10 ** 7)
read = sys.stdin.buffer.read
inp = sys.stdin.buffer.readline
def inpS(): return inp().rstrip().decode()


import copy
def resolve():
    def init_fall(grid, cell):
        col = [grid[y][cell] for y in range(H) if grid[y][cell] != 0]
        # for y in range(H):
        #     if grid[y][cell] != 0:
        #         col.append(grid[y][cell])
        col = [0] * (H - len(col)) + col
        for y in range(H):
            grid[y][cell] = col[y]
        return grid

    H, W, K = map(int, inp().split())
    mp = [list(map(int, inpS())) for _ in range(H)]

    ans = 0
    for i in range(1,H):
        for j in range(W):
            mp_copy = copy.deepcopy(mp)
            mp_copy[i][j] = 0
            mp_copy = init_fall(mp_copy,j)
            game = Game(mp_copy, H, W, K)
            game.run()
            ans = max(ans, game.score)
    print(ans)

if __name__ == "__main__":
    resolve()

Fixed submission:

import sys
sys.setrecursionlimit(10 ** 7)
read = sys.stdin.buffer.read
inp = sys.stdin.buffer.readline
def inpS(): return inp().rstrip().decode()

import copy
def resolve():
    def drop(board_copy):
        change = True
        score = 0
        p = 0
        while change:
            change = False
            for i in range(2, H + 1):
                ser = 1
                for j in range(1, W + 1):
                    if board_copy[i][j] > 0 and board_copy[i][j] == board_copy[i][j - 1]:
                        ser += 1
                    else:
                        if ser >= K:
                            score += 2 ** p * board_copy[i][j - 1] * ser
                            change = True
                            for k in range(i, 0, -1):
                                board_copy[k][j - ser:j] = board_copy[k - 1][j - ser:j]
                        ser = 1
            p += 1
        return score

    H, W, K = map(int, input().split())
    mp = []
    mp.append([0] * (W + 1))
    mp += [list(map(int, input())) + [0] for _ in range(H)]

    ans = 0
    for i in range(1, H + 1):
        for j in range(W):
            mp_copy = copy.deepcopy(mp)
            for k in range(i, 0, -1):
                mp_copy[k][j] = mp_copy[k - 1][j]
            score = drop(mp_copy)
            ans = max(ans, score)
    print(ans)

if __name__ == "__main__":
    resolve()

Buggy python submission (verdict: Time Limit Exceeded):

class Game:
    def __init__(self, mp, h, w, k):
        self.mp = mp
        self.H = h
        self.W = w

        self.K = k
        self.score = 0
        self.erase_flag = False
        self.cnt = 0
        
    def erase(self):
        tot = 0
        for y in range(self.H):
            line = self.mp[y]
            new_line, add_score = self.fix(line)
            self.mp[y] = new_line
            tot += add_score
            if add_score != 0:
                self.erase_flag = True
        if self.erase_flag:
            self.score += tot*pow(2, self.cnt)
            self.cnt += 1
    
    def fix(self, line):
        add_score = 0
        new_line = line
        for length in range(self.W, self.K-1, -1):
            for left in range(self.W - length+1):
                if all(map(lambda x:x==new_line[left], new_line[left:left+length])):
                    add_score += new_line[left]*length
                    new_line = new_line[:left] + [0]*length + new_line[left+length:]
                    # 最後の要素まで見たか？
                    # if self.W == left+length:
                    #     return new_line, add_score
        return new_line, add_score
    
    def fall(self):
        for x in range(self.W):
            col = [self.mp[y][x] for y in range(self.H) if self.mp[y][x] != 0]
            # for y in range(self.H):
            #     if self.mp[y][x] != 0:
            #         col.append(self.mp[y][x])
            col = [0]*(self.H - len(col)) + col
            for y in range(self.H):
                self.mp[y][x] = col[y]

    def run(self):
        while True:
            self.erase_flag = False
            self.erase()
            if not self.erase_flag:
                break
            self.fall()

import copy
def resolve():
    def init_fall(grid, cell):
        col = [grid[y][cell] for y in range(H) if grid[y][cell] != 0]
        # for y in range(H):
        #     if grid[y][cell] != 0:
        #         col.append(grid[y][cell])
        col = [0] * (H - len(col)) + col
        for y in range(H):
            grid[y][cell] = col[y]
        return grid

    H, W, K = map(int, input().split())
    mp = [list(map(int, input())) for _ in range(H)]

    ans = 0
    for i in range(1,H):
        for j in range(W):
            mp_copy = copy.deepcopy(mp)
            mp_copy[i][j] = 0
            mp_copy = init_fall(mp_copy,j)
            game = Game(mp_copy, H, W, K)
            game.run()
            ans = max(ans, game.score)
    print(ans)

if __name__ == "__main__":
    resolve()

Fixed submission:

import sys
sys.setrecursionlimit(10 ** 7)
read = sys.stdin.buffer.read
inp = sys.stdin.buffer.readline
def inpS(): return inp().rstrip().decode()

import copy
def resolve():
    def drop(board_copy):
        change = True
        score = 0
        p = 0
        while change:
            change = False
            for i in range(2, H + 1):
                ser = 1
                for j in range(1, W + 1):
                    if board_copy[i][j] > 0 and board_copy[i][j] == board_copy[i][j - 1]:
                        ser += 1
                    else:
                        if ser >= K:
                            score += 2 ** p * board_copy[i][j - 1] * ser
                            change = True
                            for k in range(i, 0, -1):
                                board_copy[k][j - ser:j] = board_copy[k - 1][j - ser:j]
                        ser = 1
            p += 1
        return score

    H, W, K = map(int, input().split())
    mp = []
    mp.append([0] * (W + 1))
    mp += [list(map(int, input())) + [0] for _ in range(H)]

    ans = 0
    for i in range(1, H + 1):
        for j in range(W):
            mp_copy = copy.deepcopy(mp)
            for k in range(i, 0, -1):
                mp_copy[k][j] = mp_copy[k - 1][j]
            score = drop(mp_copy)
            ans = max(ans, score)
    print(ans)

if __name__ == "__main__":
    resolve()

Buggy python submission (verdict: Time Limit Exceeded):

class Game:
    def __init__(self, mp, h, w, k):
        self.mp = mp
        self.H = h
        self.W = w

        self.K = k
        self.score = 0
        self.erase_flag = False
        self.cnt = 0
        
    def erase(self):
        tot = 0
        for y in range(self.H):
            line = self.mp[y]
            new_line, add_score = self.fix(line)
            self.mp[y] = new_line
            tot += add_score
            if add_score != 0:
                self.erase_flag = True
        if self.erase_flag:
            self.score += tot*pow(2, self.cnt)
            self.cnt += 1
    
    def fix(self, line):
        add_score = 0
        new_line = line
        for length in range(self.W, self.K-1, -1):
            for left in range(self.W - length+1):
                if all(map(lambda x:x==new_line[left], new_line[left:left+length])):
                    add_score += new_line[left]*length
                    new_line = new_line[:left] + [0]*length + new_line[left+length:]
                    # 最後の要素まで見たか？
                    # if self.W == left+length:
                    #     return new_line, add_score
        return new_line, add_score
    
    def fall(self):
        for x in range(self.W):
            col = []
            for y in range(self.H):
                if self.mp[y][x] != 0:
                    col.append(self.mp[y][x])
            col = [0]*(self.H - len(col)) + col
            for y in range(self.H):
                self.mp[y][x] = col[y]

    def run(self):
        while True:
            self.erase_flag = False
            self.erase()
            if not self.erase_flag:
                break
            self.fall()

import copy
def resolve():
    def init_fall(grid, cell):
        col = []
        for y in range(H):
            if grid[y][cell] != 0:
                col.append(grid[y][cell])
        col = [0] * (H - len(col)) + col
        for y in range(H):
            grid[y][cell] = col[y]
        return grid

    H, W, K = map(int, input().split())
    mp = [list(map(int, input())) for _ in range(H)]

    ans = 0
    for i in range(1,H):
        for j in range(W):
            mp_copy = copy.deepcopy(mp)
            mp_copy[i][j] = 0
            mp_copy = init_fall(mp_copy,j)
            game = Game(mp_copy, H, W, K)
            game.run()
            ans = max(ans, game.score)
    print(ans)

if __name__ == "__main__":
    resolve()

Fixed submission:

import sys
sys.setrecursionlimit(10 ** 7)
read = sys.stdin.buffer.read
inp = sys.stdin.buffer.readline
def inpS(): return inp().rstrip().decode()

import copy
def resolve():
    def drop(board_copy):
        change = True
        score = 0
        p = 0
        while change:
            change = False
            for i in range(2, H + 1):
                ser = 1
                for j in range(1, W + 1):
                    if board_copy[i][j] > 0 and board_copy[i][j] == board_copy[i][j - 1]:
                        ser += 1
                    else:
                        if ser >= K:
                            score += 2 ** p * board_copy[i][j - 1] * ser
                            change = True
                            for k in range(i, 0, -1):
                                board_copy[k][j - ser:j] = board_copy[k - 1][j - ser:j]
                        ser = 1
            p += 1
        return score

    H, W, K = map(int, input().split())
    mp = []
    mp.append([0] * (W + 1))
    mp += [list(map(int, input())) + [0] for _ in range(H)]

    ans = 0
    for i in range(1, H + 1):
        for j in range(W):
            mp_copy = copy.deepcopy(mp)
            for k in range(i, 0, -1):
                mp_copy[k][j] = mp_copy[k - 1][j]
            score = drop(mp_copy)
            ans = max(ans, score)
    print(ans)

if __name__ == "__main__":
    resolve()

Buggy python submission (verdict: Time Limit Exceeded):
        
class Game:
    def __init__(self, mp, h, w, k):
        self.mp = mp
        self.H = h
        self.W = w

        self.K = k
        self.score = 0
        self.erase_flag = False
        self.cnt = 0
        
    def erase(self):
        tot = 0
        for y in range(self.H):
            line = self.mp[y]
            new_line, add_score = self.fix(line)
            self.mp[y] = new_line
            tot += add_score
            if add_score != 0:
                self.erase_flag = True
        if self.erase_flag:
            self.score += tot*pow(2, self.cnt)
            self.cnt += 1
    
    def fix(self, line):
        add_score = 0
        new_line = line
        for length in range(self.W, self.K-1, -1):
            for left in range(self.W - length+1):
                if all(map(lambda x:x==new_line[left], new_line[left:left+length])):
                    add_score += new_line[left]*length
                    new_line = new_line[:left] + [0]*length + new_line[left+length:]
                    # 最後の要素まで見たか？
                    # if self.W == left+length:
                    #     return new_line, add_score
        return new_line, add_score
    
    def fall(self):
        for x in range(self.W):
            col = []
            for y in range(self.H):
                if self.mp[y][x] != 0:
                    col.append(self.mp[y][x])
            col = [0]*(self.H - len(col)) + col
            for y in range(self.H):
                self.mp[y][x] = col[y]

    def run(self):
        while True:
            self.erase_flag = False
            self.erase()
            if not self.erase_flag:
                break
            self.fall()

import copy
def resolve():
    def init_fall(grid, cell):
        col = []
        for y in range(H):
            if grid[y][cell] != 0:
                col.append(grid[y][cell])
        col = [0] * (H - len(col)) + col
        for y in range(H):
            grid[y][cell] = col[y]
        return grid

    H, W, K = map(int, input().split())
    mp = [list(map(int, input())) for _ in range(H)]

    ans = 0
    for i in range(1,H):
        for j in range(W):
            mp_copy = copy.deepcopy(mp)
            mp_copy[i][j] = 0
            mp_copy = init_fall(mp_copy,j)
            game = Game(mp_copy, H, W, K)
            game.run()
            ans = max(ans, game.score)
    print(ans)

if __name__ == "__main__":
    resolve()

Fixed submission:

import sys
sys.setrecursionlimit(10 ** 7)
read = sys.stdin.buffer.read
inp = sys.stdin.buffer.readline
def inpS(): return inp().rstrip().decode()

import copy
def resolve():
    def drop(board_copy):
        change = True
        score = 0
        p = 0
        while change:
            change = False
            for i in range(2, H + 1):
                ser = 1
                for j in range(1, W + 1):
                    if board_copy[i][j] > 0 and board_copy[i][j] == board_copy[i][j - 1]:
                        ser += 1
                    else:
                        if ser >= K:
                            score += 2 ** p * board_copy[i][j - 1] * ser
                            change = True
                            for k in range(i, 0, -1):
                                board_copy[k][j - ser:j] = board_copy[k - 1][j - ser:j]
                        ser = 1
            p += 1
        return score

    H, W, K = map(int, input().split())
    mp = []
    mp.append([0] * (W + 1))
    mp += [list(map(int, input())) + [0] for _ in range(H)]

    ans = 0
    for i in range(1, H + 1):
        for j in range(W):
            mp_copy = copy.deepcopy(mp)
            for k in range(i, 0, -1):
                mp_copy[k][j] = mp_copy[k - 1][j]
            score = drop(mp_copy)
            ans = max(ans, score)
    print(ans)

if __name__ == "__main__":
    resolve()