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):


import sys
from copy import deepcopy

def input(): return sys.stdin.readline().strip()
def ceil(x, y=1): return int(-(-x // y))
def INT(): return int(input())
def MAP(): return map(int, input().split())
def LIST(): return list(map(int, input().split()))
def Yes(): print('Yes')
def No(): print('No')
def YES(): print('YES')
def NO(): print('NO')
sys.setrecursionlimit(10 ** 9)
INF = float('inf')
MOD = 10 ** 9 + 7

H,W,K=MAP()
orgn=[[0]*W for i in range(H)]
for i in range(H):
    nums=input()
    for j in range(W):
        orgn[i][j]=int(nums[j])


def drop():
    for i in range(H-1, 0, -1):
        for j in range(W):
            if grid[i][j]==0 and grid[i-1][j]!=0:
                k=i
                while k<H and grid[k][j]==0:     
                    grid[k][j]=grid[k-1][j]
                    grid[k-1][j]=0
                    k+=1


def check(times):
    sm=0
    for i in range(H):
        st=0
        cnt=1
        for j in range(1, W):
            if grid[i][j-1]==grid[i][j]:
                cnt+=1
            else:
                if cnt>=K:
                    sm+=grid[i][j-1]*cnt
                    for k in range(st, j):
                        grid[i][k]=0
                cnt=1
                st=j
        else:
            if cnt>=K:
                sm+=grid[i][j]*cnt
                for k in range(st, j+1):
                    grid[i][k]=0
    return 2**times*sm

ans=0
for i in range(H):
    for j in range(W):
        
        grid=deepcopy(orgn)
        grid[i][j]=0    
        res=1
        score=times=0
        
        while res:
            drop()
            res=check(times)
            score+=res
            times+=1
        ans=max(ans, score)

print(ans)

Solution (Python):


import sys

def input(): return sys.stdin.readline().strip()
def ceil(x, y=1): return int(-(-x // y))
def INT(): return int(input())
def MAP(): return map(int, input().split())
def LIST(): return list(map(int, input().split()))
def Yes(): print('Yes')
def No(): print('No')
def YES(): print('YES')
def NO(): print('NO')
sys.setrecursionlimit(10 ** 9)
INF = float('inf')
MOD = 10 ** 9 + 7

def deepcopy(li):
    return [x[:] for x in li]

H,W,K=MAP()
orgn=[[0]*W for i in range(H)]
for i in range(H):
    nums=input()
    for j in range(W):
        orgn[i][j]=int(nums[j])


def drop():
    for i in range(H-1, 0, -1):
        for j in range(W):
            if grid[i][j]==0 and grid[i-1][j]!=0:
                k=i
                while k<H and grid[k][j]==0:     
                    grid[k][j]=grid[k-1][j]
                    grid[k-1][j]=0
                    k+=1


def check(times):
    sm=0
    for i in range(H):
        st=0
        cnt=1
        for j in range(1, W):
            if grid[i][j-1]==grid[i][j]:
                cnt+=1
            else:
                if cnt>=K:
                    sm+=grid[i][j-1]*cnt
                    for k in range(st, j):
                        grid[i][k]=0
                cnt=1
                st=j
        else:
            if cnt>=K:
                sm+=grid[i][j]*cnt
                for k in range(st, j+1):
                    grid[i][k]=0
    return 2**times*sm

ans=0
for i in range(H):
    for j in range(W):
        
        grid=deepcopy(orgn)
        grid[i][j]=0    
        res=1
        score=times=0
        
        while res:
            drop()
            res=check(times)
            score+=res
            times+=1
        ans=max(ans, score)

print(ans)

Solution (Python):


import sys
from copy import deepcopy

def input(): return sys.stdin.readline().strip()
def ceil(x, y=1): return int(-(-x // y))
def INT(): return int(input())
def MAP(): return map(int, input().split())
def LIST(): return list(map(int, input().split()))
def Yes(): print('Yes')
def No(): print('No')
def YES(): print('YES')
def NO(): print('NO')
sys.setrecursionlimit(10 ** 9)
INF = float('inf')
MOD = 10 ** 9 + 7

H,W,K=MAP()
orgn=[[0]*W for i in range(H)]
for i in range(H):
    nums=input()
    for j in range(W):
        orgn[i][j]=int(nums[j])

def drop():
    for i in range(H-1, 0, -1):
        for j in range(W):
            if grid[i][j]==0 and grid[i-1][j]!=0:
                k=i
                while k<H and grid[k][j]==0:     
                    grid[k][j]=grid[k-1][j]
                    grid[k-1][j]=0
                    k+=1

def check(times):
    sm=0
    for i in range(H):
        st=0
        cnt=1
        for j in range(1, W):
            if grid[i][j-1]==grid[i][j]:
                cnt+=1
            else:
                if cnt>=K:
                    sm+=grid[i][j-1]*cnt
                    for k in range(st, j):
                        grid[i][k]=0
                cnt=1
                st=j
        else:
            if cnt>=K:
                sm+=grid[i][j]*cnt
                for k in range(st, j+1):
                    grid[i][k]=0
    return 2**times*sm

ans=0
for i in range(H):
    for j in range(W):
        grid=deepcopy(orgn)
        grid[i][j]=0    
        res=1
        score=times=0
        while res:
            drop()
            res=check(times)
            score+=res
            times+=1
        ans=max(ans, score)

print(ans)

Solution (Python):
from copy import deepcopy
h,w,n = (int(i) for i in input().split())
c1,ans = [[] for i in range(w)],0
for i in range(h):
	s = input()
	for j in range(w): c1[j].append(int(s[j]))
if n<4:
	if h==30: z = 25
	else: z = h//2
	for i in range(z,h):
		for j in range(w):
			c,m,a = deepcopy(c1),0,0
			del c[j][i]
			c[j].insert(0,0)
			while 1:
				d = []
				for k in range(i-h,-h,-1):
					k2 = 0
					while k2<w-n+1:
						if c[k2][k] and all(c[k2][k]==c[k2+k3][k] for k3 in range(1,n)):
							b = n
							for k3 in range(k2+n,w):
								if c[k2][k]==c[k3][k]: b+=1
								else: break
							d.append((h+k,k2,b))
							k2+=b
						else: k2+=1
				if d:
					for k,k2,k3 in d:
						a+=(2**m)*c[k2][k]*k3
						for k4 in range(k2,k2+k3): del c[k4][k]
					for k,k2,k3 in d:
						for k4 in range(k2,k2+k3): c[k4].insert(0,0)
				else: break
				m+=1
			ans = max(ans,a)
print(ans)

Solution (Python):
from copy import deepcopy as cp

H,W,K = map(int,input().split())
src = [input() for i in range(H)]

panels = []
for cols in zip(*src):
    panels.append(list(reversed(cols)))

ans = 0
for r0 in range(H):
    for c0 in range(W):
        ps = cp(panels)
        del ps[c0][r0]
        tmp = 0
        bonus = 1
        chaining = True
        while chaining:
            chaining = False
            for r in reversed(range(H)):
                seq = 0
                prev = None
                for c in range(W):
                    if r >= len(ps[c]) or (prev and prev != ps[c][r]) or c == 0:
                        if seq >= K:
                            tmp += bonus * seq * int(prev)
                            chaining = True
                            for i in range(seq):
                                del ps[c-i-1][r]
                        if r >= len(ps[c]):
                            seq,prev = 0,None
                        else:
                            seq,prev = 1,ps[c][r]
                    elif prev:
                        seq += 1
                    else:
                        seq = 1
                        prev = ps[c][r]
                if seq >= K:
                    tmp += bonus * seq * int(prev)
                    chaining = True
                    for i in range(seq):
                        del ps[W-i-1][r]
            bonus *= 2
        ans = max(ans, tmp)
print(ans)

Solution (Python):


def dropcell(h, w, rm):
    for i in range(w):
        y = 0
        for j in range(h):
            if rm[h-j-1][i] != 0:
                rm[h-y-1][i] = rm[h-j-1][i]
                y += 1
        for j in range(h-y):
            rm[h-y-j-1][i] = 0

def removecell(h, w, k, rm, a):
    p = 0
    for y in range(h):
        c, t = 1, 0
        for i in range(w+1):
            x = rm[y][i]
            if x > 0 and x == t:
                c += 1
            else:
                if c >= k:
                    for j in range(c):
                        rm[y][i-1-j] = 0
                    p += (t * c)
                t = x
                c = 1
    return p * (2**a)

def game(h, w, k, M, y, x):
    f, score, a = 1, 0, 0
    rm = [[j for j in i]for i in M[:y+1]]
    rm[y][x] = 0
    while f:
        dropcell(len(rm), w, rm)
        f = removecell(len(rm), w, k, rm, a)
        score += f
        a += 1
    return score

def main():
    H, W, K = map(int, input().split())
    M = [list(map(int, list(input())))+[0] for i in range(H)]
    ans = 0
    for j in range(W):
        t = 0
        for i in range(1, H):
            if M[i][j] != t:
                ans = max(ans, game(H, W, K, M, i, j))
                t = M[i][j]
    print(ans)
    
if __name__ == '__main__':
    main()

Solution (Python):
def main():
    h, w, k = map(int, raw_input().split())
    c = [map(int, raw_input().strip()) for _ in xrange(h)]
    def go(a):
        if not res:
            return 0
        return go(a) * 2 + res
    ans = 0
    for ii in xrange(h):
        for jj in xrange(w):
            a = [c[i][:] for i in xrange(h)]
            a[ii][jj] = 0
            r = 0
            e = 1
            while 1:
                for j in xrange(w):
                    st = [a[i][j] for i in xrange(h) if a[i][j]]
                    for i in xrange(h):
                        a[i][j] = 0
                    i = -1
                    for x in reversed(st):
                        a[i][j] = x
                        i -= 1
                res = 0
                for i in xrange(h):
                    j = 0
                    while j < w:
                        t = j + 1
                        while t < w and a[i][j] == a[i][t]:
                            t += 1
                        if t - j >= k:
                            for j in xrange(j, t):
                                res += a[i][j]
                                a[i][j] = 0
                        j = t
                if not res:
                    break
                r += res * e
                e *= 2
            if ans < r:
                ans = r
    print ans
main()