Problem:
  Max Score: $300$ Points   Problem Statement We are playing a puzzle. An upright board with $H$ rows by $W$ columns of cells, is used in this puzzle. A stone in $i$-th row and $j$-th column engraved with a digit, one of 1 through 9, is placed in each of the cells. You can erase 1 cell in the board.  The game process is following:   When $K$ or more stones in horizontally adjacent cells are engraved with the same digit, the stones will disappear. Disappearances of all such groups of stones take place simultaneously.  When stones are in the cells above the emptied cells, these stones drop down so that the emptied cells are filled.  After the completion of all stone drops, if one or more groups of stones satisfy the disappearance condition, repeat by returning to the step 1.  Score is $\sum_i 2^i \times \left(\text{Sum of numbers in the stones which disappeared in the $i$-th chain (0-indexed)}\right)$.  Please answer the points if he erased the optimal place.        Input The input is given from standard input in the following format.

Solution (Python):
from copy import deepcopy
H, W, K = map(int, input().split())
board = [[0]*W for _ in range(H+1)]
for i in range(1,H+1):
    board[i] = list(map(int, list(input())))
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(W):
                if j==W-1:
                    if ser>=K:
                        score += 2**p*board_copy[i][-1]*ser
                        change = True
                        for k in range(i,0,-1):
                            board_copy[k][j-ser+1:] = board_copy[k-1][j-ser+1:]
                    continue
                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]*ser
                        change = True
                        for k in range(i,0,-1):
                            board_copy[k][j-ser+1:j+1] = board_copy[k-1][j-ser+1:j+1]
                    ser = 1
        p += 1
    return score
ans = 0
for h in range(1,H+1):
    for w in range(W):
        board_copy = deepcopy(board)
        for k in range(h,0,-1):
            board_copy[k][w] = board[k-1][w]
        ans = max(ans,drop(board_copy))
print(ans)

Solution (Python):
h, w, k  = map(int, input().split())

puyo_orig = [[0]*w for _ in range(h+1)]
for i in range(1,h+1):
    puyo_orig[i] = list(map(int, list(input())))

import copy
mx = 0
for i1 in range(2,h+1):
    for i2 in range(w):
        puyo = copy.deepcopy(puyo_orig)
        for l in range(i1,0,-1):
            puyo[l][i2] = puyo[l-1][i2]
        p = 0
        fin = 0
        turn = 0
        while fin==0:
            fin = 1
            for i in range(2,h+1):
                cnt = 1
                for j in range(w-1):
                    if puyo[i][j+1] == puyo[i][j] and puyo[i][j]>0:
                        cnt += 1
                    else:
                        if cnt>=k:
                            p += cnt * puyo[i][j] * 2**turn
                            for l in range(i,0,-1):
                                puyo[l][j-cnt+1:j+1] = puyo[l-1][j-cnt+1:j+1]
                            fin = 0
                        cnt = 1
                    if j==w-2:
                        if cnt>=k:
                            p += cnt * puyo[i][j] * 2**turn
                            for l in range(i,0,-1):
                                puyo[l][j-cnt+2:] = puyo[l-1][j-cnt+2:]
                            fin = 0
            turn += 1
        if p>mx:
            mx=p
            
print(mx)

Solution (Python):
h, w, k  = map(int, input().split())

puyo_orig = [[0]*w for _ in range(h+1)]
for i in range(1,h+1):
    puyo_orig[i] = list(map(int, list(input())))

import copy
mx = 0
for i1 in range(2,h+1):
    for i2 in range(w):
        puyo = copy.deepcopy(puyo_orig)
        for l in range(i1,0,-1):
            puyo[l][i2] = puyo[l-1][i2]
        p = 0
        fin = 0
        turn = 0
        while fin==0:
            fin = 1
            for i in range(2,h+1):
                cnt = 1
                for j in range(w-1):
                    if puyo[i][j+1] == puyo[i][j] and puyo[i][j]>0:
                        cnt += 1
                    else:
                        if cnt>=k:
                            p += cnt * puyo[i][j] * 2**turn
                            for l in range(i,0,-1):
                                puyo[l][j-cnt+1:j+1] = puyo[l-1][j-cnt+1:j+1]
                            fin = 0
                        cnt = 1
                    if j==w-2:
                        if cnt>=k:
                            p += cnt * puyo[i][j] * 2**turn
                            for l in range(i,0,-1):
                                puyo[l][j-cnt+2:j+2] = puyo[l-1][j-cnt+2:j+2]
                            fin = 0
            turn += 1
        if p>mx:
            mx=p
            
print(mx)

Solution (Python):
h, w, k  = map(int, input().split())

puyo_orig = [[0]*w for _ in range(h+1)]
for i in range(1,h+1):
    puyo_orig[i] = list(map(int, list(input())))

import copy
mx = 0
for i1 in range(2,h+1):
    for i2 in range(w):
        puyo = copy.deepcopy(puyo_orig)
        for l in range(i1,0,-1):
            puyo[l][i2] = puyo[l-1][i2]
        p = 0
        fin = 0
        turn = 0
        while fin==0:
            fin = 1
            for i in range(2,h+1):
                cnt = 1
                for j in range(1,w):
                    if puyo[i][j-1] == puyo[i][j] and puyo[i][j]>0:
                        cnt += 1
                    else:
                        if cnt>=k:
                            p += cnt * puyo[i][j-1] * 2**turn
                            for l in range(i,0,-1):
                                puyo[l][j-cnt:j] = puyo[l-1][j-cnt:j]
                            fin = 0
                        cnt = 1
                    if j==w-1:
                        if cnt>=k:
                            p += cnt * puyo[i][j-1] * 2**turn
                            for l in range(i,0,-1):
                                puyo[l][j-cnt+1:j+1] = puyo[l-1][j-cnt+1:j+1]
                            fin = 0
            turn += 1
        if p>mx:
            mx=p
            
print(mx)

Solution (Python):
h, w, k  = map(int, input().split())

puyo_orig = [list(map(int, list(input()))) for _ in range(h)]

import copy
mx = 0
for i1 in range(1,h):
    for i2 in range(w):
        puyo = copy.deepcopy(puyo_orig)
        for l in range(i1,0,-1):
            puyo[l][i2] = puyo[l-1][i2]
        puyo[0][i2]=0
        p = 0
        fin = 0
        turn = 0
        while fin==0:
            fin = 1
            for i in range(1,h):
                cnt = 1
                for j in range(1, w):
                    if puyo[i][j-1] == puyo[i][j] and puyo[i][j]>0:
                        cnt += 1
                    else:
                        if cnt>=k:
                            p += cnt * puyo[i][j-1] * 2**turn
                            for l in range(i,0,-1):
                                puyo[l][j-cnt:j] = puyo[l-1][j-cnt:j]
                            puyo[0][j-cnt:j] = [0]*cnt
                            fin = 0
                        cnt = 1
                    if j==w-1:
                        if cnt>=k:
                            p += cnt * puyo[i][j-1] * 2**turn
                            for l in range(i,0,-1):
                                puyo[l][j-cnt+1:j+1] = puyo[l-1][j-cnt+1:j+1]
                            puyo[0][j-cnt+1:j+1] = [0]*cnt
                            fin = 0
            turn += 1
        if p>mx:
            mx=p
            
print(mx)

Solution (Python):
h, w, k  = map(int, input().split())

puyo_orig = [list(map(int, list(input()))) for _ in range(h)]

import copy
mx = 0
for i1 in range(h):
    for i2 in range(w):
        puyo = copy.deepcopy(puyo_orig)
        puyo[i1][i2] = -1
        p = 0
        fin = 0
        turn = 0
        while fin==0:
            
            fin = 1
            
            for i in range(w):
                d_fin = 0
                while d_fin==0:
                    d_fin = 1
                    for j in range(h-1, 0, -1):
                        if puyo[j][i]==-1 and puyo[j-1][i]>0:
                            puyo[j][i] = puyo[j-1][i]
                            puyo[j-1][i] = -1
                            d_fin = 0
                            
            for i in range(h):
                cnt = 1
                for j in range(1, w):
                    if puyo[i][j-1] == puyo[i][j] and puyo[i][j]>0:
                        cnt += 1
                    else:
                        if cnt>=k:
                            p += cnt * puyo[i][j-1] * 2**turn
                            for k2 in range(cnt):
                                puyo[i][j-k2-1] = -1
                                fin = 0
                        cnt = 1
                    if j==w-1:
                        if cnt>=k:
                            p += cnt * puyo[i][j-1] * 2**turn
                            for k2 in range(cnt):
                                puyo[i][j-k2] = -1
                                fin = 0
            turn += 1
        if p>mx:
            mx=p
            
print(mx)

Solution (Python):
import copy
import sys
read = sys.stdin.read
readline = sys.stdin.readline
readlines = sys.stdin.readlines

def main():
    ans = 0
    H,W,K = map(int, readline().split())
    c_ = [list(map(int, list(readline().strip()))) for _ in range(H)]

    for a in range(H):
        for b in range(W):
            c = copy.deepcopy(c_)
            c[a][b] = 0

            seq = [[1] for _ in range(H)]
            ans_tmp = [0]
            
            score = 0
            weight = 1
            while True:
                
                for i in reversed(range(H)):
                    for j in range(W):
                        if c[i][j] == 0:
                            for h in reversed(range(i)):
                                if c[h][j] != 0:
                                    c[h][j], c[i][j] = c[i][j], c[h][j]
                                    break

                
                for i, line in enumerate(c):
                    for j in range(1,W):
                        if line[j] == line[j-1]:
                            seq[i][-1] += 1
                        else:
                            seq[i].append(1)
                
                    acc = -1
                    for s in seq[i]:
                        acc += s
                        if s >= K:
                            score += s * line[acc] * weight
                            for j in range(acc - s + 1, acc + 1):
                                line[j] = 0
                    seq[i] = [1]
                
                weight *= 2

                ans_tmp.append(score)
                if ans_tmp[-1] == ans_tmp[-2]:
                    ans = max(ans, ans_tmp[-1])
                    break

    print(ans)


if __name__ == "__main__":
    main()

Solution (Python):
import copy
import sys
read = sys.stdin.read
readline = sys.stdin.readline
readlines = sys.stdin.readlines

def main():
    ans = []
    H,W,K = map(int, readline().split())
    c_ = [list(map(int, list(readline().strip()))) for _ in range(H)]

    for a in range(H):
        for b in range(W):
            c = copy.deepcopy(c_)
            c[a][b] = 0

            seq = [[1] for _ in range(H)]
            ans_tmp = [0]
            
            score = 0
            weight = 1
            while True:
                
                for i in reversed(range(H)):
                    for j in range(W):
                        if c[i][j] == 0:
                            for h in reversed(range(i)):
                                if c[h][j] != 0:
                                    c[h][j], c[i][j] = c[i][j], c[h][j]
                                    break

                
                for i, line in enumerate(c):
                    for j in range(1,W):
                        if line[j] == line[j-1]:
                            seq[i][-1] += 1
                        else:
                            seq[i].append(1)
                
                    acc = -1
                    for s in seq[i]:
                        acc += s
                        if s >= K:
                            score += s * line[acc] * weight
                            for j in range(acc - s + 1, acc + 1):
                                line[j] = 0
                    seq[i] = [1]
                
                weight *= 2

                ans_tmp.append(score)
                if ans_tmp[-1] == ans_tmp[-2]:
                    ans.append(ans_tmp[-1])
                    break

    print(max(ans))


if __name__ == "__main__":
    main()

Solution (Python):
h, w, k  = map(int, input().split())

puyo_orig = [list(map(int, list(input()))) for _ in range(h)]

import copy
mx = 0
for i1 in range(h):
    for i2 in range(w):
        puyo = copy.deepcopy(puyo_orig)
        puyo[i1][i2] = -1
        p = 0
        fin = 0
        turn = 0
        while fin==0:
            
            fin = 1
            
            for i in range(w):
                d_fin = 0
                while d_fin==0:
                    d_fin = 1
                    for j in range(h-1, 0, -1):
                        if puyo[j][i]==-1 and puyo[j-1][i]>0:
                            puyo[j][i] = puyo[j-1][i]
                            puyo[j-1][i] = -1
                            d_fin = 0
                            
            for i in range(h):
                cnt = 1
                for j in range(1, w):
                    if puyo[i][j-1] == puyo[i][j] and puyo[i][j]>0:
                        cnt += 1
                    else:
                        if cnt>=k:
                            p += cnt * puyo[i][j-1] * 2**turn
                            for k2 in range(cnt):
                                puyo[i][j-k2-1] = -1
                                fin = 0
                        cnt = 1
                    if j==w-1:
                        if cnt>=k:
                            p += cnt * puyo[i][j-1] * 2**turn
                            for k2 in range(cnt):
                                puyo[i][j-k2] = -1
                                fin = 0
            turn += 1
        if p>mx:
            mx=p
            
print(mx)

Solution (Python):
import copy

h, w, k = map(int, input().split())
c = [list(map(int, list(input()))) for _ in range(h)]
c.insert(0, [0] * w)
maxscore = 0
for i in range(1, h + 1):
    for j in range(w):
        if i == 1:
            maxscore = max(maxscore, c[i][j])
        else:
            s = copy.deepcopy(c)
            s[i][j] = 0
            score = 0
            p = 1
            while True:
                for m in range(w):
                    z = 0
                    x = []
                    for l in range(i + 1):
                        if s[l][m] != 0:
                            x.append(s[l][m])
                    x = [0] * (i + 1 - len(x)) + x
                    for l in range(i + 1):
                        s[l][m] = x[l]
                b = 0
                for l in range(1, i + 1):
                    n = s[l][0]
                    cnt = 0
                    for m in range(w):
                        if s[l][m] == n and s[l][m] != 0:
                            cnt += 1
                        else:
                            if cnt >= k:
                                b = 1
                                for ii in range(m - cnt, m):
                                    s[l][ii] = 0
                                    score += p * n
                            n = s[l][m]
                            if s[l][m] != 0:
                                cnt = 1
                            else:
                                cnt = 0
                    if cnt >= k:
                        b = 1
                        for ii in range(w - cnt, w):
                            s[l][ii] = 0
                            score += p * n
                if b == 0:
                    break
                p *= 2
            maxscore = max(maxscore, score)

print(maxscore)

Solution (Python):
from sys import setrecursionlimit, exit
setrecursionlimit(1000000000)

from heapq import heapify, heappush, heappop, heappushpop, heapreplace
from bisect import bisect_left, bisect_right

from math import atan, degrees

h, w, k = map(int, input().split())
ori = [list(map(int, list(input()))) for _ in range(h)]
ori.reverse()
ans = 0
for x in range(w):
    for y in range(h - 1):
        data = [[ori[i][j] for j in range(w)] for i in range(h)]
        for i in range(y, h - 1):
            data[i][x] = data[i+1][x]
        data[h-1][x] = 0
        score = 0
        lc = 1
        nxt = True
        while nxt:
            nxt = False
            for i in range(h):
                c = 1
                for j in range(1, w):
                    if data[i][j] != 0 and data[i][j] == data[i][j-1]:
                        c += 1
                    else:
                        if c >= k:
                            nxt = True
                            score += data[i][j-1] * c * lc
                            for l in range(j - c, j):
                                data[i][l] = 0
                        c = 1
                if c >= k:
                    nxt = True
                    score += data[i][w-1] * c * lc
                    for l in range(w - c, w):
                        data[i][l] = 0
            for j in range(w):
                z = 0
                for i in range(h):
                    if data[i][j] == 0:
                        z += 1
                    elif z > 0:
                        data[i-z][j] = data[i][j]
                        data[i][j] = 0
            lc *= 2
        ans = max(ans, score)
        if score == 0:
            break
print(ans)

Solution (Python):

import sys
import math
import string
import collections
import fractions
import random
from operator import itemgetter
import itertools
from collections import deque
import copy
import heapq
import bisect

MOD = 10 ** 9 + 7
INF = float('inf')
input = lambda: sys.stdin.readline().strip()

sys.setrecursionlimit(10 ** 8)

H, W, K = map(int, input().split())
c = [list(map(int, list(input()))) for _ in range(H)]
ans = 0
cc = copy.deepcopy(c)
for z in range(H):
    for m in range(W):
        c = copy.deepcopy(cc)
        c[z][m] = 0
        temp_ans = 0
        repeat_num = -1
        p = 1
        while p:
            p = 0
            for i in range(H):
                num = 1
                for j in range(W):
                    if j != W - 1:
                        if c[i][j] == c[i][j + 1] and c[i][j] != -1:
                            num += 1
                        elif num >= K:
                            temp_ans += 2 ** repeat_num * c[i][j] * num
                            for k in range(j - num + 1, j + 1):
                                c[i][k] = 0
                            num = 1
                            p = 1
                        else:
                            num = 1
                    elif num >= K:
                        temp_ans += 2 ** repeat_num * c[i][j] * num
                        for k in range(j - num + 1, j + 1):
                            c[i][k] = 0
                        num = 1
                        p = 1
            for i in reversed(range(H)):
                for j in reversed(range(W)):
                    if not c[i][j]:
                        if i == 0:
                            c[i][j] = -1
                        else:
                            for k in reversed(range(i)):
                                if c[k][j] != 0:
                                    c[i][j] = c[k][j]
                                    c[k][j] = 0
                                    break
            repeat_num += 1
            if repeat_num == 0:
                p = 1
        ans = max(ans, temp_ans)
print(ans)

Solution (Python):
from copy import deepcopy
import sys
def main():
  input=sys.stdin.readline
  h,w,k=map(int,input().split())
  grid=[]
  for _ in range(h):
    s=input().rstrip()
    s=list(s)
    s=list(map(int,s))
    grid.append(s)
  def score(t):
    total=0
    for i in range(1,h):
      for j in range(w-1):
        cnt=1
        ten=gc[i][j]
        while gc[i][j+1]==gc[i][j]:
          cnt+=1
          j+=1
          if j==w-1:
            break
        if cnt>=k:
          total+=2**t*(ten*cnt)
          gc[i][j-cnt+1:j+1]=[0]*cnt
    return total
  def upd():
    while 1:
      ok=True
      for i in range(1,h):
        for j in range(w):
          if gc[i][j]==0 and gc[i-1][j]!=0:
            x=gc[i-1][j]
            gc[i-1][j]=0
            gc[i][j]=x
            ok=False
      if ok:
        return
  ans=0
  for i in range(1,h):
    for j in range(w):
      gc=deepcopy(grid)
      gc[i][j]=0
      t=0
      res=0
      while 1:
        upd()
        total=score(t)
        if total==0:
          break
        t+=1
        res+=total
      ans=max(ans,res)
  return print(ans)
if __name__=='__main__':
  main()

Solution (Python):

from collections import defaultdict, deque
from heapq import heappush, heappop
from itertools import permutations, accumulate
import sys
import math
import bisect
def LI(): return [int(x) for x in sys.stdin.readline().split()]
def I(): return int(sys.stdin.readline())
def LS():return [list(x) for x in sys.stdin.readline().split()]
def S():
    res = list(sys.stdin.readline())
    if res[-1] == "\n":
        return res[:-1]
    return res
def IR(n):
    return [I() for i in range(n)]
def LIR(n):
    return [LI() for i in range(n)]
def SR(n):
    return [S() for i in range(n)]
def LSR(n):
    return [LS() for i in range(n)]

sys.setrecursionlimit(1000000)
mod = 1000000007

def solve():
    def check(y,x):
        a = s[x][y]
        d = 0
        for i in range(x,w):
            if s[i][y] != a:
                break
            d += 1
        if d < k:
            return 0
        else:
            return d

    def update(y,x,d):
        for i in range(x,x+d):
            s[i][y] = 0

    def fall(s):
        res = [[] for i in range(w)]
        for x in range(w):
            for y in range(h):
                if s[x][y]:
                    res[x].append(s[x][y])
            for y in range(h-len(res[x])):
                res[x].append(0)
        return res

    h,w,k = LI()
    c = [list(map(int, input())) for i in range(h)]
    c = [[c[-1-y][x] for y in range(h)] for x in range(w)]
    ans = 0
    for sy in range(h):
        for sx in range(w):
            s = [[i for i in j] for j in c]
            s[sx][sy] = 0
            s = fall(s)
            m = 0
            is_update = 1
            p = 1
            while is_update:
                is_update = 0
                for y in range(h):
                    for x in range(w):
                        if s[x][y]:
                            d = check(y,x)
                            if d:
                                m += p*d*s[x][y]
                                update(y,x,d)
                                is_update = 1
                if is_update:
                    s = fall(s)
                    p <<= 1
            if ans < m:
                ans = m
    print(ans)
    return


if __name__ == "__main__":
    solve()

Solution (Python):
'''
https://atcoder.jp/contests/s8pc-3/tasks/s8pc_3_b
'''
def main():
    import sys
    input = sys.stdin.readline
    sys.setrecursionlimit(10000000)
    from collections import Counter, deque
    
    from itertools import combinations, permutations, accumulate
    
    from bisect import bisect_left,bisect_right
    import heapq
    from math import floor, ceil
    

    
    

    h,w,k = map(int, input().split())
    banmen = []
    for _ in range(h):
        s = input().rstrip()
        s = list(s)
        s = list(map(int, s))
        banmen.append(s)

    def update():
        while 1:
            cnt = 0
            for i in range(h-1):
                for j in range(w):
                    if c[i+1][j] == 0 and c[i][j] != 0:
                        c[i][j], c[i+1][j] = c[i+1][j], c[i][j]
                        cnt += 1
            if cnt == 0:
                return

    
    def get(n):
        total = 0
        for i in range(h):
            for j in range(0, w-k+1, 1):
                ten = c[i][j]
                cnt = 1
                while c[i][j] == c[i][j+1]:
                    cnt += 1
                    j += 1
                    if j == w-1:
                        break
                if cnt >= k:
                    total += 2**n * (ten*cnt)
                    c[i][j-(cnt-1):j+1] = [0]*cnt
        return total

    def solve(i, j):
        c[i][j] = 0
        res = 0
        n = 0
        while 1:
            update()
            total = get(n)
            if total == 0:
                break
            n += 1
            res += total
        return res

    import copy
    res = 0
    for i in range(h):
        for j in range(w):
            c = copy.deepcopy(banmen) 
            res = max(res, solve(i, j))
    print(res)

if __name__ == '__main__':
    main()

Solution (Python):
import sys,queue,math,copy
LI = lambda : [int(x) for x in input().split()]

H,W,K = LI()
C = [[int(x) for x in input()] + [0] for _ in range(H)]

max_p = 0
for a in range(H):
    for b in range(W):
        c = copy.deepcopy(C)
        c[a][b] = 0
        p = 0
        for x in range(a,0,-1):
            c[x][b] = c[x-1][b]
        c[0][b] = 0


        update = True
        cnt = 0
        while update:
            update = False

            for i in range(H):
                n = c[i][0]
                nc = n > 0
                for j in range(1, W + 1):
                    if c[i][j] == n and n > 0:
                        nc += 1
                    else:
                        if nc >= K:
                            for k in range(nc):
                                c[i][j-k-1] = 0
                            p += nc * n * (2 **cnt)
                            update = True
                        n = c[i][j]
                        nc = n > 0

            for i in range(H-1, 0, -1):
                for j in range(W):
                    if c[i][j] > 0: continue
                    x = i
                    while x > 0:
                        x -= 1
                        if c[x][j] > 0:
                            c[i][j] = c[x][j]
                            c[x][j] = 0
                            break
            cnt += 1

        max_p = max(max_p,p)
print (max_p)

Solution (Python):
import sys,queue,math,copy
LI = lambda : [int(x) for x in input().split()]

H,W,K = LI()
C = [[int(x) for x in input()] + [0] for _ in range(H)]

max_p = 0
for i in range(H):
    for j in range(W):
        c = copy.deepcopy(C)
        c[i][j] = 0
        p = 0
        for ii in range(i,0,-1):
            c[ii][j] = c[ii-1][j]
        c[0][j] = 0


        update = True
        cnt = 0
        while update:
            update = False

            for ii in range(H):
                n = c[ii][0]
                nc = n > 0
                for jj in range(1, W + 1):
                    if c[ii][jj] == n and n > 0:
                        nc += 1
                    else:
                        if nc >= K:
                            for k in range(nc):
                                c[ii][jj-k-1] = 0
                            p += nc * n * (2 **cnt)
                            update = True
                        n = c[ii][jj]
                        nc = n > 0

            for ii in range(H-1, 0, -1):
                for jj in range(W):
                    if c[ii][jj] > 0: continue
                    x = ii
                    while x > 0:
                        x -= 1
                        if c[x][jj] > 0:
                            c[ii][jj] = c[x][jj]
                            c[x][jj] = 0
                            break
            cnt += 1

        max_p = max(max_p,p)
print (max_p)

Solution (Python):
import copy
H,W,K = map(int,input().split())
A = [list(map(int,list(input()))) for _ in range(H)]
scrmax = 0
for i in range(1,H):
    for j in range(W):
        cnt = 0
        scr = 0
        B = copy.deepcopy(A)
        B[i][j] = 0
        for k in range(i,0,-1):
            B[k][j] = B[k-1][j]
            B[k-1][j] = 0
        while True:
            flg = 0
            for i1 in range(H):
                C = []
                while True:
                    flg1 = 0
                    cur = 0
                    m = 0
                    b = -1
                    ind = -1
                    for j1 in range(1,W):
                        if B[i1][j1]>0 and B[i1][j1]==B[i1][j1-1]:continue
                        else:
                            if B[i1][cur]>0 and j1-cur>m:
                                m = j1-cur
                                b = B[i1][cur]
                                ind = cur
                            cur = j1
                    if B[i1][cur]>0 and W-cur>m:
                        m = W-cur
                        b = B[i1][cur]
                        ind = cur
                    if m>=K:
                        flg = 1
                        flg1 = 1
                        scr += 2**cnt*b*m
                        B[i1][ind:ind+m] = [0 for _ in range(m)]
                        C.append([ind,m])
                    if flg1==0:break
                for ind,m in C:
                    for j1 in range(ind,ind+m):
                        for k in range(i1,0,-1):
                            B[k][j1] = B[k-1][j1]
                            B[k-1][j1] = 0
            if flg==0:break
            cnt += 1
        scrmax = max(scrmax,scr)     
print(scrmax)

Solution (Python):
import sys
read = sys.stdin.buffer.read
readline = sys.stdin.buffer.readline
readlines = sys.stdin.buffer.readlines

import time
start = time.time()

import numpy as np

H,W,K = map(int,readline().split())
S = np.array([list(line.rstrip()) for line in readlines()]).astype(np.int8) - ord('0')


S = S[::-1].T

def drop(S):
    for i in range(W):
        col = S[i]
        S[i] = drop_col(col)

def drop_col(col):
    x = np.zeros(H,np.int8)
    nonzero = col[col != 0]
    x[:len(nonzero)] = nonzero
    return x

def cnt_connection(S):
    
    x = np.ones_like(S)
    equal = (S[:-1] == S[1:])
    for i in range(1,W):
        x[i] = x[i-1] * equal[i-1] + 1
    for i in range(W-2,-1,-1):
        x[i][equal[i]] = x[i+1][equal[i]]
    return x

def simulate(S,turn):
    
    drop(S)
    conn = cnt_connection(S)
    remove = (conn >= K)
    before = S.sum()
    S *= (~remove)
    after = S.sum()
    if before == after:
        
        return 0
    else:
        x = simulate(S,turn+1)
        return x + ((before - after) << turn)

def calc(j):
    T = S.copy()
    T[j,0] = 0
    return simulate(T,0)

answer = 0
for i in range(H):
    x = max(calc(j) for j in range(W))
    if answer < x:
        answer = x
    H -= 1
    S = S[:,1:]
    if time.time() - start > 0.9:
        break
print(answer)