Buggy python submission (verdict: Time Limit Exceeded):
def main():
    #import numpy as np
    import sys, math
    from itertools import permutations, combinations
    from collections import defaultdict, Counter, deque
    from math import factorial#, gcd
    from bisect import bisect_left #bisect_left(list, value)
    sys.setrecursionlimit(10**7)
    enu = enumerate
    MOD = 10**9+7
    def input(): return sys.stdin.readline()[:-1]
    pl = lambda x: print(*x, sep='\n')

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

    from copy import deepcopy
    cS = [[0]*(W+1) for _ in range(H+1)]
    # cS = deepcopy(S)

    for h in range(1, H+1):
        for w in range(W):
            cS[h][w+1] = cS[h][w] + S[h-1][w]
    for w in range(1, W+1):
        for h in range(H):
            cS[h+1][w] = cS[h][w] + cS[h+1][w]
    # pl(cS)

    mcut = 10**9
    for i in range(2**(H-1)):
        yoko = []
        for j in range(H):
            if ((i >> j) & 1):
                yoko.append(j+1)
        yoko = [0] + yoko + [H]
        # yoko.append(H)
        # print(yoko)
        
        cut = len(yoko)-2
        lastcut = 0 # index-w
        w = 1
        while w < W+1:
            cannot = False
            for ind, y in enu(yoko):
                if cannot:
                    w = W + 100
                    break
                if ind == 0:
                    continue
                v1 = cS[y][w]
                v2 = cS[yoko[ind-1]][w]
                v3 = cS[yoko[ind-1]][lastcut]
                v4 = cS[y][lastcut]
                val = v1 - v2 + v3 - v4
                # print('  v1, v2', v1, v2)
                if K < val:
                    cut += 1
                    if lastcut == w-1:
                        cannot = True
                    lastcut = w-1
                    break
            else:
                w += 1
            # print(' val', val)
        if cut < mcut:
            mcut = cut

    print(mcut)
if __name__ == '__main__':
    main()

Fixed submission:
def main():
    #import numpy as np
    import sys, math
    from itertools import permutations, combinations
    from collections import defaultdict, Counter, deque
    from math import factorial#, gcd
    from bisect import bisect_left #bisect_left(list, value)
    sys.setrecursionlimit(10**7)
    enu = enumerate
    MOD = 10**9+7
    def input(): return sys.stdin.readline()[:-1]
    pl = lambda x: print(*x, sep='\n')

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

    from copy import deepcopy
    cS = [[0]*(W+1) for _ in range(H+1)]
    # cS = deepcopy(S)

    for h in range(1, H+1):
        for w in range(W):
            cS[h][w+1] = cS[h][w] + S[h-1][w]
    for w in range(1, W+1):
        for h in range(H):
            cS[h+1][w] = cS[h][w] + cS[h+1][w]
    # pl(cS)

    mcut = 10**9
    for i in range(2**(H-1)):
        yoko = []
        for j in range(H):
            if ((i >> j) & 1):
                yoko.append(j+1)
        yoko = [0] + yoko + [H]
        # yoko.append(H)
        # print(yoko)
        
        cut = len(yoko)-2
        lastcut = 0 # index-w
        w = 1
        cannot = False
        while w < W+1:
            if cannot:
                w = W + 100
                break
            for ind, y in enu(yoko):
                if ind == 0:
                    continue
                v1 = cS[y][w]
                v2 = cS[yoko[ind-1]][w]
                v3 = cS[yoko[ind-1]][lastcut]
                v4 = cS[y][lastcut]
                val = v1 - v2 + v3 - v4
                # print('  v1, v2', v1, v2)
                if K < val:
                    cut += 1
                    if lastcut == w-1:
                        cannot = True
                    lastcut = w-1
                    break
            else:
                w += 1
            # print(' val', val)
        if not(cannot) and cut < mcut:
            # print('yoko', yoko)
            mcut = cut

    print(mcut)
if __name__ == '__main__':
    main()

Buggy python submission (verdict: Time Limit Exceeded):
def main():
    #import numpy as np
    import sys, math
    from itertools import permutations, combinations
    from collections import defaultdict, Counter, deque
    from math import factorial#, gcd
    from bisect import bisect_left #bisect_left(list, value)
    sys.setrecursionlimit(10**7)
    enu = enumerate
    MOD = 10**9+7
    def input(): return sys.stdin.readline()[:-1]
    pl = lambda x: print(*x, sep='\n')

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

    from copy import deepcopy
    cS = [[0]*(W+1) for _ in range(H+1)]
    # cS = deepcopy(S)

    for h in range(1, H+1):
        for w in range(W):
            cS[h][w+1] = cS[h][w] + S[h-1][w]
    for w in range(1, W+1):
        for h in range(H):
            cS[h+1][w] = cS[h][w] + cS[h+1][w]
    # pl(cS)

    mcut = 10**9
    for i in range(2**(H-1)):
        yoko = []
        for j in range(H):
            if ((i >> j) & 1):
                yoko.append(j+1)
        yoko = [0] + yoko + [H]
        # yoko.append(H)
        # print(yoko)
        
        cut = len(yoko)-2
        lastcut = 0 # index-w
        w = 1
        while w < W+1:
            for ind, y in enu(yoko):
                if ind == 0:
                    continue
                v1 = cS[y][w]
                v2 = cS[yoko[ind-1]][w]
                v3 = cS[yoko[ind-1]][lastcut]
                v4 = cS[y][lastcut]
                val = v1 - v2 + v3 - v4
                # print('  v1, v2', v1, v2)
                if K < val:
                    cut += 1
                    lastcut = w-1
                    break
            else:
                w += 1
            # print(' val', val)
        if cut < mcut:
            mcut = cut

    print(mcut)
if __name__ == '__main__':
    main()

Fixed submission:
def main():
    #import numpy as np
    import sys, math
    from itertools import permutations, combinations
    from collections import defaultdict, Counter, deque
    from math import factorial#, gcd
    from bisect import bisect_left #bisect_left(list, value)
    sys.setrecursionlimit(10**7)
    enu = enumerate
    MOD = 10**9+7
    def input(): return sys.stdin.readline()[:-1]
    pl = lambda x: print(*x, sep='\n')

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

    from copy import deepcopy
    cS = [[0]*(W+1) for _ in range(H+1)]
    # cS = deepcopy(S)

    for h in range(1, H+1):
        for w in range(W):
            cS[h][w+1] = cS[h][w] + S[h-1][w]
    for w in range(1, W+1):
        for h in range(H):
            cS[h+1][w] = cS[h][w] + cS[h+1][w]
    # pl(cS)

    mcut = 10**9
    for i in range(2**(H-1)):
        yoko = []
        for j in range(H):
            if ((i >> j) & 1):
                yoko.append(j+1)
        yoko = [0] + yoko + [H]
        # yoko.append(H)
        # print(yoko)
        
        cut = len(yoko)-2
        lastcut = 0 # index-w
        w = 1
        cannot = False
        while w < W+1:
            if cannot:
                w = W + 100
                break
            for ind, y in enu(yoko):
                if ind == 0:
                    continue
                v1 = cS[y][w]
                v2 = cS[yoko[ind-1]][w]
                v3 = cS[yoko[ind-1]][lastcut]
                v4 = cS[y][lastcut]
                val = v1 - v2 + v3 - v4
                # print('  v1, v2', v1, v2)
                if K < val:
                    cut += 1
                    if lastcut == w-1:
                        cannot = True
                    lastcut = w-1
                    break
            else:
                w += 1
            # print(' val', val)
        if not(cannot) and cut < mcut:
            # print('yoko', yoko)
            mcut = cut

    print(mcut)
if __name__ == '__main__':
    main()

Buggy python submission (verdict: Time Limit Exceeded):
#import numpy as np
import sys, math
from itertools import permutations, combinations
from collections import defaultdict, Counter, deque
from math import factorial#, gcd
from bisect import bisect_left #bisect_left(list, value)
sys.setrecursionlimit(10**7)
enu = enumerate
MOD = 10**9+7
def input(): return sys.stdin.readline()[:-1]
pl = lambda x: print(*x, sep='\n')

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

from copy import deepcopy
cS = [[0]*(W+1) for _ in range(H+1)]
# cS = deepcopy(S)

for h in range(1, H+1):
    for w in range(W):
        cS[h][w+1] = cS[h][w] + S[h-1][w]
for w in range(1, W+1):
    for h in range(H):
        cS[h+1][w] = cS[h][w] + cS[h+1][w]
# pl(cS)

mcut = 10**9
for i in range(2**(H-1)):
    yoko = []
    for j in range(H):
        if ((i >> j) & 1):
            yoko.append(j+1)
    yoko = [0] + yoko + [H]
    # yoko.append(H)
    # print(yoko)
    
    cut = len(yoko)-2
    lastcut = 0 # index-w
    w = 1
    while w < W+1:
        for ind, y in enu(yoko):
            if ind == 0:
                continue
            v1 = cS[y][w]
            v2 = cS[yoko[ind-1]][w]
            v3 = cS[yoko[ind-1]][lastcut]
            v4 = cS[y][lastcut]
            val = v1 - v2 + v3 - v4
            # print('  v1, v2', v1, v2)
            if K < val:
                cut += 1
                lastcut = w-1
                break
        else:
            w += 1
        # print(' val', val)

    mcut = min(mcut, cut)
print(mcut)

Fixed submission:
def main():
    #import numpy as np
    import sys, math
    from itertools import permutations, combinations
    from collections import defaultdict, Counter, deque
    from math import factorial#, gcd
    from bisect import bisect_left #bisect_left(list, value)
    sys.setrecursionlimit(10**7)
    enu = enumerate
    MOD = 10**9+7
    def input(): return sys.stdin.readline()[:-1]
    pl = lambda x: print(*x, sep='\n')

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

    from copy import deepcopy
    cS = [[0]*(W+1) for _ in range(H+1)]
    # cS = deepcopy(S)

    for h in range(1, H+1):
        for w in range(W):
            cS[h][w+1] = cS[h][w] + S[h-1][w]
    for w in range(1, W+1):
        for h in range(H):
            cS[h+1][w] = cS[h][w] + cS[h+1][w]
    # pl(cS)

    mcut = 10**9
    for i in range(2**(H-1)):
        yoko = []
        for j in range(H):
            if ((i >> j) & 1):
                yoko.append(j+1)
        yoko = [0] + yoko + [H]
        # yoko.append(H)
        # print(yoko)
        
        cut = len(yoko)-2
        lastcut = 0 # index-w
        w = 1
        cannot = False
        while w < W+1:
            if cannot:
                w = W + 100
                break
            for ind, y in enu(yoko):
                if ind == 0:
                    continue
                v1 = cS[y][w]
                v2 = cS[yoko[ind-1]][w]
                v3 = cS[yoko[ind-1]][lastcut]
                v4 = cS[y][lastcut]
                val = v1 - v2 + v3 - v4
                # print('  v1, v2', v1, v2)
                if K < val:
                    cut += 1
                    if lastcut == w-1:
                        cannot = True
                    lastcut = w-1
                    break
            else:
                w += 1
            # print(' val', val)
        if not(cannot) and cut < mcut:
            # print('yoko', yoko)
            mcut = cut

    print(mcut)
if __name__ == '__main__':
    main()

Buggy python submission (verdict: Runtime Error):
# import numpy as np
import sys, math
from itertools import permutations, combinations
from collections import defaultdict, Counter, deque
from math import factorial#, gcd
from bisect import bisect_left #bisect_left(list, value)
sys.setrecursionlimit(10**7)
enu = enumerate
MOD = 10**9+7
#def input(): return sys.stdin.readline()[:-1]
pl = lambda x: print(*x, sep='\n')
from copy import copy, deepcopy

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

# for h in range(H):
#     for w in range(W):
#         cumS[h+1][w+1] += cumS[h+1][w]
for h in range(H):
    for w in range(W):
        print(h, w)
        cumS[h+1][w+1] += S[h][w]
        cumS[h+1][w+1] += cumS[h][w+1]

n = H-1
cut_min = 10**9
for i in range(2**n):
    cut = 0
    # print('i:', i)
    yoko = [0]
    for j in range(n):
        if ((i>>j) & 1):
            yoko.append(j+1)

    cut += len(yoko) - 1
    # tate
    yoko = yoko + [H]
    cnt = [0]*(len(yoko)-1)
    ncnt = [0]*(len(yoko)-1)
    for j in range(W):
        for k, (y1, y2) in enu(zip(yoko[:-1], yoko[1:])):
            ncnt[k] = cumS[y2][j+1] - cumS[y1][j+1]

        for ind, nc in enu(ncnt):
            cnt[ind] += nc
            if K < cnt[ind]:
                cut += 1
                cnt = ncnt.copy()
                break
    #     print(cnt)
    # print(cut)
    cut_min = min(cut_min, cut)
print(cut_min)

Fixed submission:
def main():
    #import numpy as np
    import sys, math
    from itertools import permutations, combinations
    from collections import defaultdict, Counter, deque
    from math import factorial#, gcd
    from bisect import bisect_left #bisect_left(list, value)
    sys.setrecursionlimit(10**7)
    enu = enumerate
    MOD = 10**9+7
    def input(): return sys.stdin.readline()[:-1]
    pl = lambda x: print(*x, sep='\n')

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

    from copy import deepcopy
    cS = [[0]*(W+1) for _ in range(H+1)]
    # cS = deepcopy(S)

    for h in range(1, H+1):
        for w in range(W):
            cS[h][w+1] = cS[h][w] + S[h-1][w]
    for w in range(1, W+1):
        for h in range(H):
            cS[h+1][w] = cS[h][w] + cS[h+1][w]
    # pl(cS)

    mcut = 10**9
    for i in range(2**(H-1)):
        yoko = []
        for j in range(H):
            if ((i >> j) & 1):
                yoko.append(j+1)
        yoko = [0] + yoko + [H]
        # yoko.append(H)
        # print(yoko)
        
        cut = len(yoko)-2
        lastcut = 0 # index-w
        w = 1
        cannot = False
        while w < W+1:
            if cannot:
                w = W + 100
                break
            for ind, y in enu(yoko):
                if ind == 0:
                    continue
                v1 = cS[y][w]
                v2 = cS[yoko[ind-1]][w]
                v3 = cS[yoko[ind-1]][lastcut]
                v4 = cS[y][lastcut]
                val = v1 - v2 + v3 - v4
                # print('  v1, v2', v1, v2)
                if K < val:
                    cut += 1
                    if lastcut == w-1:
                        cannot = True
                    lastcut = w-1
                    break
            else:
                w += 1
            # print(' val', val)
        if not(cannot) and cut < mcut:
            # print('yoko', yoko)
            mcut = cut

    print(mcut)
if __name__ == '__main__':
    main()

Buggy python submission (verdict: Runtime Error):
# import numpy as np
import sys, math
from itertools import permutations, combinations
from collections import defaultdict, Counter, deque
from math import factorial#, gcd
from bisect import bisect_left #bisect_left(list, value)
sys.setrecursionlimit(10**7)
enu = enumerate
MOD = 10**9+7
def input(): return sys.stdin.readline()[:-1]
pl = lambda x: print(*x, sep='\n')
from copy import copy, deepcopy

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

# for h in range(H):
#     for w in range(W):
#         cumS[h+1][w+1] += cumS[h+1][w]
for h in range(H):
    for w in range(W):
        print(h, w)
        cumS[h+1][w+1] += S[h][w]
        cumS[h+1][w+1] += cumS[h][w+1]

n = H-1
cut_min = 10**9
for i in range(2**n):
    cut = 0
    # print('i:', i)
    yoko = [0]
    for j in range(n):
        if ((i>>j) & 1):
            yoko.append(j+1)

    cut += len(yoko) - 1
    # tate
    yoko = yoko + [H]
    cnt = [0]*(len(yoko)-1)
    ncnt = [0]*(len(yoko)-1)
    for j in range(W):
        for k, (y1, y2) in enu(zip(yoko[:-1], yoko[1:])):
            ncnt[k] = cumS[y2][j+1] - cumS[y1][j+1]

        for ind, nc in enu(ncnt):
            cnt[ind] += nc
            if K < cnt[ind]:
                cut += 1
                cnt = ncnt.copy()
                break
    #     print(cnt)
    # print(cut)
    cut_min = min(cut_min, cut)
print(cut_min)

Fixed submission:
def main():
    #import numpy as np
    import sys, math
    from itertools import permutations, combinations
    from collections import defaultdict, Counter, deque
    from math import factorial#, gcd
    from bisect import bisect_left #bisect_left(list, value)
    sys.setrecursionlimit(10**7)
    enu = enumerate
    MOD = 10**9+7
    def input(): return sys.stdin.readline()[:-1]
    pl = lambda x: print(*x, sep='\n')

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

    from copy import deepcopy
    cS = [[0]*(W+1) for _ in range(H+1)]
    # cS = deepcopy(S)

    for h in range(1, H+1):
        for w in range(W):
            cS[h][w+1] = cS[h][w] + S[h-1][w]
    for w in range(1, W+1):
        for h in range(H):
            cS[h+1][w] = cS[h][w] + cS[h+1][w]
    # pl(cS)

    mcut = 10**9
    for i in range(2**(H-1)):
        yoko = []
        for j in range(H):
            if ((i >> j) & 1):
                yoko.append(j+1)
        yoko = [0] + yoko + [H]
        # yoko.append(H)
        # print(yoko)
        
        cut = len(yoko)-2
        lastcut = 0 # index-w
        w = 1
        cannot = False
        while w < W+1:
            if cannot:
                w = W + 100
                break
            for ind, y in enu(yoko):
                if ind == 0:
                    continue
                v1 = cS[y][w]
                v2 = cS[yoko[ind-1]][w]
                v3 = cS[yoko[ind-1]][lastcut]
                v4 = cS[y][lastcut]
                val = v1 - v2 + v3 - v4
                # print('  v1, v2', v1, v2)
                if K < val:
                    cut += 1
                    if lastcut == w-1:
                        cannot = True
                    lastcut = w-1
                    break
            else:
                w += 1
            # print(' val', val)
        if not(cannot) and cut < mcut:
            # print('yoko', yoko)
            mcut = cut

    print(mcut)
if __name__ == '__main__':
    main()

Buggy python submission (verdict: Runtime Error):
# import numpy as np
import sys, math
from itertools import permutations, combinations
from collections import defaultdict, Counter, deque
from math import factorial#, gcd
from bisect import bisect_left #bisect_left(list, value)
sys.setrecursionlimit(10**7)
enu = enumerate
MOD = 10**9+7
def input(): return sys.stdin.readline()[:-1]
pl = lambda x: print(*x, sep='\n')
from copy import deepcopy

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

# for h in range(H):
#     for w in range(W):
#         cumS[h+1][w+1] += cumS[h+1][w]
for h in range(H):
    for w in range(W):
        cumS[h+1][w+1] += S[h][w]
        cumS[h+1][w+1] += cumS[h][w+1]

n = H-1
cut_min = 10**9
for i in range(2**n):
    cut = 0
    # print('i:', i)
    yoko = []
    for j in range(n):
        if ((i>>j) & 1):
            yoko.append(j+1)

    cut += len(yoko)
    # tate
    yoko = [0] + yoko + [H]
    # cnt = np.array([0]*(len(yoko)-1))
    cnt = [0]*(len(yoko)-1)
    ncnt = [0]*(len(yoko)-1)
    for j in range(W):
        for k, (y1, y2) in enu(zip(yoko[:-1], yoko[1:])):
            # print('npS[y1:y2, j]', npS[y1:y2, j])
            ncnt[k] = cumS[y2][j+1] - cumS[y1][j+1]
        # ncnt = np.array(ncnt)
        for ind, nc in enu(ncnt):
            cnt[ind] += ncnt[ind]
            if K < cnt[ind]:
                cut += 1
                cnt = ncnt.copy()
                break
    #     print(cnt)
    # print(cut)
    cut_min = min(cut_min, cut)
print(cut_min)

Fixed submission:
def main():
    #import numpy as np
    import sys, math
    from itertools import permutations, combinations
    from collections import defaultdict, Counter, deque
    from math import factorial#, gcd
    from bisect import bisect_left #bisect_left(list, value)
    sys.setrecursionlimit(10**7)
    enu = enumerate
    MOD = 10**9+7
    def input(): return sys.stdin.readline()[:-1]
    pl = lambda x: print(*x, sep='\n')

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

    from copy import deepcopy
    cS = [[0]*(W+1) for _ in range(H+1)]
    # cS = deepcopy(S)

    for h in range(1, H+1):
        for w in range(W):
            cS[h][w+1] = cS[h][w] + S[h-1][w]
    for w in range(1, W+1):
        for h in range(H):
            cS[h+1][w] = cS[h][w] + cS[h+1][w]
    # pl(cS)

    mcut = 10**9
    for i in range(2**(H-1)):
        yoko = []
        for j in range(H):
            if ((i >> j) & 1):
                yoko.append(j+1)
        yoko = [0] + yoko + [H]
        # yoko.append(H)
        # print(yoko)
        
        cut = len(yoko)-2
        lastcut = 0 # index-w
        w = 1
        cannot = False
        while w < W+1:
            if cannot:
                w = W + 100
                break
            for ind, y in enu(yoko):
                if ind == 0:
                    continue
                v1 = cS[y][w]
                v2 = cS[yoko[ind-1]][w]
                v3 = cS[yoko[ind-1]][lastcut]
                v4 = cS[y][lastcut]
                val = v1 - v2 + v3 - v4
                # print('  v1, v2', v1, v2)
                if K < val:
                    cut += 1
                    if lastcut == w-1:
                        cannot = True
                    lastcut = w-1
                    break
            else:
                w += 1
            # print(' val', val)
        if not(cannot) and cut < mcut:
            # print('yoko', yoko)
            mcut = cut

    print(mcut)
if __name__ == '__main__':
    main()

Buggy python submission (verdict: Time Limit Exceeded):
import numpy as np
import sys, math
from itertools import permutations, combinations
from collections import defaultdict, Counter, deque
from math import factorial#, gcd
from bisect import bisect_left #bisect_left(list, value)
sys.setrecursionlimit(10**7)
enu = enumerate
MOD = 10**9+7
def input(): return sys.stdin.readline()[:-1]
pl = lambda x: print(*x, sep='\n')
from copy import deepcopy

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

# for h in range(H):
#     for w in range(W):
#         cumS[h+1][w+1] += cumS[h+1][w]
for h in range(H):
    for w in range(W):
        cumS[h+1][w+1] += S[h][w]
        cumS[h+1][w+1] += cumS[h][w+1]

n = H-1
cut_min = 10**9
for i in range(2**n):
    cut = 0
    # print('i:', i)
    yoko = []
    for j in range(n):
        if ((i>>j) & 1):
            yoko.append(j+1)

    cut += len(yoko)
    # tate
    yoko = [0] + yoko + [H]
    cnt = np.array([0]*(len(yoko)-1))
    ncnt = [0]*(len(yoko)-1)
    for j in range(W):
        for k, (y1, y2) in enu(zip(yoko[:-1], yoko[1:])):
            # print('npS[y1:y2, j]', npS[y1:y2, j])
            ncnt[k] = cumS[y2][j+1] - cumS[y1][j+1]
        ncnt = np.array(ncnt)

        if any(K < cnt+ncnt):
            cut += 1
            cnt = ncnt.copy()
        else:
            cnt += ncnt
    #     print(cnt)
    # print(cut)
    cut_min = min(cut_min, cut)
print(cut_min)

Fixed submission:
def main():
    #import numpy as np
    import sys, math
    from itertools import permutations, combinations
    from collections import defaultdict, Counter, deque
    from math import factorial#, gcd
    from bisect import bisect_left #bisect_left(list, value)
    sys.setrecursionlimit(10**7)
    enu = enumerate
    MOD = 10**9+7
    def input(): return sys.stdin.readline()[:-1]
    pl = lambda x: print(*x, sep='\n')

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

    from copy import deepcopy
    cS = [[0]*(W+1) for _ in range(H+1)]
    # cS = deepcopy(S)

    for h in range(1, H+1):
        for w in range(W):
            cS[h][w+1] = cS[h][w] + S[h-1][w]
    for w in range(1, W+1):
        for h in range(H):
            cS[h+1][w] = cS[h][w] + cS[h+1][w]
    # pl(cS)

    mcut = 10**9
    for i in range(2**(H-1)):
        yoko = []
        for j in range(H):
            if ((i >> j) & 1):
                yoko.append(j+1)
        yoko = [0] + yoko + [H]
        # yoko.append(H)
        # print(yoko)
        
        cut = len(yoko)-2
        lastcut = 0 # index-w
        w = 1
        cannot = False
        while w < W+1:
            if cannot:
                w = W + 100
                break
            for ind, y in enu(yoko):
                if ind == 0:
                    continue
                v1 = cS[y][w]
                v2 = cS[yoko[ind-1]][w]
                v3 = cS[yoko[ind-1]][lastcut]
                v4 = cS[y][lastcut]
                val = v1 - v2 + v3 - v4
                # print('  v1, v2', v1, v2)
                if K < val:
                    cut += 1
                    if lastcut == w-1:
                        cannot = True
                    lastcut = w-1
                    break
            else:
                w += 1
            # print(' val', val)
        if not(cannot) and cut < mcut:
            # print('yoko', yoko)
            mcut = cut

    print(mcut)
if __name__ == '__main__':
    main()

Buggy python submission (verdict: Time Limit Exceeded):
import numpy as np
import sys, math
from itertools import permutations, combinations
from collections import defaultdict, Counter, deque
from math import factorial#, gcd
from bisect import bisect_left #bisect_left(list, value)
sys.setrecursionlimit(10**7)
enu = enumerate
MOD = 10**9+7
def input(): return sys.stdin.readline()[:-1]
pl = lambda x: print(*x, sep='\n')
from copy import deepcopy

H, W, K = map(int, input().split())
S = [list(map(int, input())) for _ in range(H)]
cumS = [[0]*(W+1) for _ in range(H+1)]
for h in range(H):
    for w in range(W):
        cumS[h+1][w+1] = S[h][w]

# for h in range(H):
#     for w in range(W):
#         cumS[h+1][w+1] += cumS[h+1][w]
for h in range(H):
    for w in range(W):
        cumS[h+1][w+1] += cumS[h][w+1]

n = H-1
cut_min = 10**9
for i in range(2**n):
    cut = 0
    # print('i:', i)
    yoko = []
    for j in range(n):
        if ((i>>j) & 1):
            yoko.append(j+1)

    cut += len(yoko)
    # tate
    yoko = [0] + yoko + [H]
    cnt = np.array([0]*(len(yoko)-1))
    ncnt = [0]*(len(yoko)-1)
    for j in range(W):
        for k, (y1, y2) in enu(zip(yoko[:-1], yoko[1:])):
            # print('npS[y1:y2, j]', npS[y1:y2, j])
            ncnt[k] = cumS[y2][j+1] - cumS[y1][j+1]
        ncnt = np.array(ncnt)

        if any(K < cnt+ncnt):
            cut += 1
            cnt = ncnt.copy()
        else:
            cnt += ncnt
    #     print(cnt)
    # print(cut)
    cut_min = min(cut_min, cut)
print(cut_min)

Fixed submission:
def main():
    #import numpy as np
    import sys, math
    from itertools import permutations, combinations
    from collections import defaultdict, Counter, deque
    from math import factorial#, gcd
    from bisect import bisect_left #bisect_left(list, value)
    sys.setrecursionlimit(10**7)
    enu = enumerate
    MOD = 10**9+7
    def input(): return sys.stdin.readline()[:-1]
    pl = lambda x: print(*x, sep='\n')

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

    from copy import deepcopy
    cS = [[0]*(W+1) for _ in range(H+1)]
    # cS = deepcopy(S)

    for h in range(1, H+1):
        for w in range(W):
            cS[h][w+1] = cS[h][w] + S[h-1][w]
    for w in range(1, W+1):
        for h in range(H):
            cS[h+1][w] = cS[h][w] + cS[h+1][w]
    # pl(cS)

    mcut = 10**9
    for i in range(2**(H-1)):
        yoko = []
        for j in range(H):
            if ((i >> j) & 1):
                yoko.append(j+1)
        yoko = [0] + yoko + [H]
        # yoko.append(H)
        # print(yoko)
        
        cut = len(yoko)-2
        lastcut = 0 # index-w
        w = 1
        cannot = False
        while w < W+1:
            if cannot:
                w = W + 100
                break
            for ind, y in enu(yoko):
                if ind == 0:
                    continue
                v1 = cS[y][w]
                v2 = cS[yoko[ind-1]][w]
                v3 = cS[yoko[ind-1]][lastcut]
                v4 = cS[y][lastcut]
                val = v1 - v2 + v3 - v4
                # print('  v1, v2', v1, v2)
                if K < val:
                    cut += 1
                    if lastcut == w-1:
                        cannot = True
                    lastcut = w-1
                    break
            else:
                w += 1
            # print(' val', val)
        if not(cannot) and cut < mcut:
            # print('yoko', yoko)
            mcut = cut

    print(mcut)
if __name__ == '__main__':
    main()

Buggy python submission (verdict: Time Limit Exceeded):
import numpy as np
import sys, math
from itertools import permutations, combinations
from collections import defaultdict, Counter, deque
from math import factorial#, gcd
from bisect import bisect_left #bisect_left(list, value)
sys.setrecursionlimit(10**7)
enu = enumerate
MOD = 10**9+7
def input(): return sys.stdin.readline()[:-1]
pl = lambda x: print(*x, sep='\n')

H, W, K = map(int, input().split())
S = [list(map(int, input())) for _ in range(H)]
npS = np.array(S)

n = H-1
cut_min = 10**9
for i in range(2**n):
    cut = 0
    # print('i:', i)
    yoko = []
    for j in range(n):
        if ((i>>j) & 1):
            yoko.append(j+1)

    # print(yoko)
    cut += len(yoko)
    # tate
    cnt = np.array([0]*(len(yoko)+1))
    yoko = [0] + yoko + [H]
    for j in range(W):
        ncnt = []
        for k, (y1, y2) in enu(zip(yoko[:-1], yoko[1:])):
            # print('npS[y1:y2, j]', npS[y1:y2, j])
            ncnt.append(np.count_nonzero(npS[y1:y2, j]))
        ncnt = np.array(ncnt)
        # print('ncnt', ncnt)

        if any(K < cnt+ncnt):
            cut += 1
            cnt = ncnt
        else:
            cnt += ncnt

    # print(cut)
    cut_min = min(cut_min, cut)
print(cut_min)


Fixed submission:
def main():
    #import numpy as np
    import sys, math
    from itertools import permutations, combinations
    from collections import defaultdict, Counter, deque
    from math import factorial#, gcd
    from bisect import bisect_left #bisect_left(list, value)
    sys.setrecursionlimit(10**7)
    enu = enumerate
    MOD = 10**9+7
    def input(): return sys.stdin.readline()[:-1]
    pl = lambda x: print(*x, sep='\n')

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

    from copy import deepcopy
    cS = [[0]*(W+1) for _ in range(H+1)]
    # cS = deepcopy(S)

    for h in range(1, H+1):
        for w in range(W):
            cS[h][w+1] = cS[h][w] + S[h-1][w]
    for w in range(1, W+1):
        for h in range(H):
            cS[h+1][w] = cS[h][w] + cS[h+1][w]
    # pl(cS)

    mcut = 10**9
    for i in range(2**(H-1)):
        yoko = []
        for j in range(H):
            if ((i >> j) & 1):
                yoko.append(j+1)
        yoko = [0] + yoko + [H]
        # yoko.append(H)
        # print(yoko)
        
        cut = len(yoko)-2
        lastcut = 0 # index-w
        w = 1
        cannot = False
        while w < W+1:
            if cannot:
                w = W + 100
                break
            for ind, y in enu(yoko):
                if ind == 0:
                    continue
                v1 = cS[y][w]
                v2 = cS[yoko[ind-1]][w]
                v3 = cS[yoko[ind-1]][lastcut]
                v4 = cS[y][lastcut]
                val = v1 - v2 + v3 - v4
                # print('  v1, v2', v1, v2)
                if K < val:
                    cut += 1
                    if lastcut == w-1:
                        cannot = True
                    lastcut = w-1
                    break
            else:
                w += 1
            # print(' val', val)
        if not(cannot) and cut < mcut:
            # print('yoko', yoko)
            mcut = cut

    print(mcut)
if __name__ == '__main__':
    main()

Buggy python submission (verdict: Time Limit Exceeded):
import numpy as np
from copy import deepcopy
import sys, math
from itertools import permutations, combinations
from collections import defaultdict, Counter, deque
from math import factorial#, gcd
from bisect import bisect_left #bisect_left(list, value)
sys.setrecursionlimit(10**7)
enu = enumerate
MOD = 10**9+7
def input(): return sys.stdin.readline()[:-1]
def pri(x): print('\n'.join(map(str, x)))

H, W, K = map(int, input().split())
SHW = [list(map(int, list(input()))) for _ in range(H)]
SHW = np.array(SHW)
tSHW = SHW.T

def vcut(cuts: list):
    num = 0
    cuts = [0] + cuts + [H]

    iparts = [0]*(len(cuts)-1)
    parts = deepcopy(iparts)
    w = 0
    while w < W:
        for i, (sc, ec) in enu(zip(cuts, cuts[1:])):
            if K < parts[i]+sum(tSHW[w][sc:ec]):
                num += 1
                parts = deepcopy(iparts)
                break
            else:
                parts[i] += sum(tSHW[w][sc:ec])
        else:
            w += 1
    return num

res = (H-1)*(W-1)
for i in range(2**(H-1)):
    cnt = 0
    cuts = [] # cut index
    for j in range((H-1)):
        if ((i >> j) & 1):
            cnt += 1
            cuts.append(j+1)
    if res > cnt:
        cnt += vcut(cuts)
        if res > cnt:
            res = cnt

print(res)



Fixed submission:
def main():
    #import numpy as np
    import sys, math
    from itertools import permutations, combinations
    from collections import defaultdict, Counter, deque
    from math import factorial#, gcd
    from bisect import bisect_left #bisect_left(list, value)
    sys.setrecursionlimit(10**7)
    enu = enumerate
    MOD = 10**9+7
    def input(): return sys.stdin.readline()[:-1]
    pl = lambda x: print(*x, sep='\n')

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

    from copy import deepcopy
    cS = [[0]*(W+1) for _ in range(H+1)]
    # cS = deepcopy(S)

    for h in range(1, H+1):
        for w in range(W):
            cS[h][w+1] = cS[h][w] + S[h-1][w]
    for w in range(1, W+1):
        for h in range(H):
            cS[h+1][w] = cS[h][w] + cS[h+1][w]
    # pl(cS)

    mcut = 10**9
    for i in range(2**(H-1)):
        yoko = []
        for j in range(H):
            if ((i >> j) & 1):
                yoko.append(j+1)
        yoko = [0] + yoko + [H]
        # yoko.append(H)
        # print(yoko)
        
        cut = len(yoko)-2
        lastcut = 0 # index-w
        w = 1
        cannot = False
        while w < W+1:
            if cannot:
                w = W + 100
                break
            for ind, y in enu(yoko):
                if ind == 0:
                    continue
                v1 = cS[y][w]
                v2 = cS[yoko[ind-1]][w]
                v3 = cS[yoko[ind-1]][lastcut]
                v4 = cS[y][lastcut]
                val = v1 - v2 + v3 - v4
                # print('  v1, v2', v1, v2)
                if K < val:
                    cut += 1
                    if lastcut == w-1:
                        cannot = True
                    lastcut = w-1
                    break
            else:
                w += 1
            # print(' val', val)
        if not(cannot) and cut < mcut:
            # print('yoko', yoko)
            mcut = cut

    print(mcut)
if __name__ == '__main__':
    main()

Buggy python submission (verdict: Time Limit Exceeded):
#import numpy as np
from copy import deepcopy
import sys, math
from itertools import permutations, combinations
from collections import defaultdict, Counter, deque
from math import factorial#, gcd
from bisect import bisect_left #bisect_left(list, value)
sys.setrecursionlimit(10**7)
enu = enumerate
MOD = 10**9+7
def input(): return sys.stdin.readline()[:-1]
def pri(x): print('\n'.join(map(str, x)))

H, W, K = map(int, input().split())
SHW = [list(map(int, list(input()))) for _ in range(H)]
tSHW = list(zip(*SHW))

def vcut(cuts: list):
    num = 0
    cuts = [0] + cuts + [H]

    iparts = [0]*(len(cuts)-1)
    parts = deepcopy(iparts)
    w = 0
    while w < W:
        for i, (sc, ec) in enu(zip(cuts, cuts[1:])):
            if K < parts[i]+sum(tSHW[w][sc:ec]):
                num += 1
                parts = deepcopy(iparts)
                break
            else:
                parts[i] += sum(tSHW[w][sc:ec])
        else:
            w += 1
    return num

res = (H-1)*(W-1)
for i in range(2**(H-1)):
    cnt = 0
    cuts = [] # cut index
    for j in range((H-1)):
        if ((i >> j) & 1):
            cnt += 1
            cuts.append(j+1)
    if res > cnt:
        cnt += vcut(cuts)
        if res > cnt:
            res = cnt

print(res)



Fixed submission:
def main():
    #import numpy as np
    import sys, math
    from itertools import permutations, combinations
    from collections import defaultdict, Counter, deque
    from math import factorial#, gcd
    from bisect import bisect_left #bisect_left(list, value)
    sys.setrecursionlimit(10**7)
    enu = enumerate
    MOD = 10**9+7
    def input(): return sys.stdin.readline()[:-1]
    pl = lambda x: print(*x, sep='\n')

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

    from copy import deepcopy
    cS = [[0]*(W+1) for _ in range(H+1)]
    # cS = deepcopy(S)

    for h in range(1, H+1):
        for w in range(W):
            cS[h][w+1] = cS[h][w] + S[h-1][w]
    for w in range(1, W+1):
        for h in range(H):
            cS[h+1][w] = cS[h][w] + cS[h+1][w]
    # pl(cS)

    mcut = 10**9
    for i in range(2**(H-1)):
        yoko = []
        for j in range(H):
            if ((i >> j) & 1):
                yoko.append(j+1)
        yoko = [0] + yoko + [H]
        # yoko.append(H)
        # print(yoko)
        
        cut = len(yoko)-2
        lastcut = 0 # index-w
        w = 1
        cannot = False
        while w < W+1:
            if cannot:
                w = W + 100
                break
            for ind, y in enu(yoko):
                if ind == 0:
                    continue
                v1 = cS[y][w]
                v2 = cS[yoko[ind-1]][w]
                v3 = cS[yoko[ind-1]][lastcut]
                v4 = cS[y][lastcut]
                val = v1 - v2 + v3 - v4
                # print('  v1, v2', v1, v2)
                if K < val:
                    cut += 1
                    if lastcut == w-1:
                        cannot = True
                    lastcut = w-1
                    break
            else:
                w += 1
            # print(' val', val)
        if not(cannot) and cut < mcut:
            # print('yoko', yoko)
            mcut = cut

    print(mcut)
if __name__ == '__main__':
    main()

Buggy python submission (verdict: Time Limit Exceeded):
#import numpy as np
from copy import deepcopy
import sys, math
from itertools import permutations, combinations
from collections import defaultdict, Counter, deque
from math import factorial#, gcd
from bisect import bisect_left #bisect_left(list, value)
sys.setrecursionlimit(10**7)
enu = enumerate
MOD = 10**9+7
def input(): return sys.stdin.readline()[:-1]
def pri(x): print('\n'.join(map(str, x)))
def solve():
    H, W, K = map(int, input().split())
    SHW = [list(map(int, list(input()))) for _ in range(H)]
    tSHW = list(zip(*SHW))

    def vcut(cuts: list):
        num = 0
        cuts = [0] + cuts + [H]

        iparts = [0]*(len(cuts)-1)
        parts = deepcopy(iparts)
        w = 0
        while w < W:
            for i, (sc, ec) in enu(zip(cuts, cuts[1:])):
                if K < parts[i]+sum(tSHW[w][sc:ec]):
                    num += 1
                    parts = deepcopy(iparts)
                    break
                else:
                    parts[i] += sum(tSHW[w][sc:ec])
            else:
                w += 1
        return num

    res = (H-1)*(W-1)
    for i in range(2**(H-1)):
        cnt = 0
        cuts = [] # cut index
        for j in range((H-1)):
            if ((i >> j) & 1):
                cnt += 1
                cuts.append(j+1)
        cnt += vcut(cuts)
        if res > cnt:
            res = cnt

    print(res)

if __name__=='__main__':
    solve()	

Fixed submission:
def main():
    #import numpy as np
    import sys, math
    from itertools import permutations, combinations
    from collections import defaultdict, Counter, deque
    from math import factorial#, gcd
    from bisect import bisect_left #bisect_left(list, value)
    sys.setrecursionlimit(10**7)
    enu = enumerate
    MOD = 10**9+7
    def input(): return sys.stdin.readline()[:-1]
    pl = lambda x: print(*x, sep='\n')

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

    from copy import deepcopy
    cS = [[0]*(W+1) for _ in range(H+1)]
    # cS = deepcopy(S)

    for h in range(1, H+1):
        for w in range(W):
            cS[h][w+1] = cS[h][w] + S[h-1][w]
    for w in range(1, W+1):
        for h in range(H):
            cS[h+1][w] = cS[h][w] + cS[h+1][w]
    # pl(cS)

    mcut = 10**9
    for i in range(2**(H-1)):
        yoko = []
        for j in range(H):
            if ((i >> j) & 1):
                yoko.append(j+1)
        yoko = [0] + yoko + [H]
        # yoko.append(H)
        # print(yoko)
        
        cut = len(yoko)-2
        lastcut = 0 # index-w
        w = 1
        cannot = False
        while w < W+1:
            if cannot:
                w = W + 100
                break
            for ind, y in enu(yoko):
                if ind == 0:
                    continue
                v1 = cS[y][w]
                v2 = cS[yoko[ind-1]][w]
                v3 = cS[yoko[ind-1]][lastcut]
                v4 = cS[y][lastcut]
                val = v1 - v2 + v3 - v4
                # print('  v1, v2', v1, v2)
                if K < val:
                    cut += 1
                    if lastcut == w-1:
                        cannot = True
                    lastcut = w-1
                    break
            else:
                w += 1
            # print(' val', val)
        if not(cannot) and cut < mcut:
            # print('yoko', yoko)
            mcut = cut

    print(mcut)
if __name__ == '__main__':
    main()

Buggy python submission (verdict: Time Limit Exceeded):
#import numpy as np
from copy import deepcopy
import sys, math
from itertools import permutations, combinations
from collections import defaultdict, Counter, deque
from math import factorial#, gcd
from bisect import bisect_left #bisect_left(list, value)
sys.setrecursionlimit(10**7)
enu = enumerate
MOD = 10**9+7
def input(): return sys.stdin.readline()[:-1]
def pri(x): print('\n'.join(map(str, x)))

H, W, K = map(int, input().split())
SHW = [list(map(int, list(input()))) for _ in range(H)]
tSHW = list(zip(*SHW))

def vcut(cuts: list):
    num = 0
    cuts = [0] + cuts + [H]

    iparts = [0]*(len(cuts)-1)
    parts = deepcopy(iparts)
    w = 0
    while w < W:
        for i, (sc, ec) in enu(zip(cuts, cuts[1:])):
            if K < parts[i]+sum(tSHW[w][sc:ec]):
                num += 1
                parts = deepcopy(iparts)
                break
            else:
                parts[i] += sum(tSHW[w][sc:ec])
        else:
            w += 1
    return num

res = (H-1)*(W-1)
for i in range(2**(H-1)):
    cnt = 0
    cuts = [] # cut index
    for j in range((H-1)):
        if ((i >> j) & 1):
            cnt += 1
            cuts.append(j+1)
    cnt += vcut(cuts)
    if res > cnt:
        res = cnt

print(res)



Fixed submission:
def main():
    #import numpy as np
    import sys, math
    from itertools import permutations, combinations
    from collections import defaultdict, Counter, deque
    from math import factorial#, gcd
    from bisect import bisect_left #bisect_left(list, value)
    sys.setrecursionlimit(10**7)
    enu = enumerate
    MOD = 10**9+7
    def input(): return sys.stdin.readline()[:-1]
    pl = lambda x: print(*x, sep='\n')

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

    from copy import deepcopy
    cS = [[0]*(W+1) for _ in range(H+1)]
    # cS = deepcopy(S)

    for h in range(1, H+1):
        for w in range(W):
            cS[h][w+1] = cS[h][w] + S[h-1][w]
    for w in range(1, W+1):
        for h in range(H):
            cS[h+1][w] = cS[h][w] + cS[h+1][w]
    # pl(cS)

    mcut = 10**9
    for i in range(2**(H-1)):
        yoko = []
        for j in range(H):
            if ((i >> j) & 1):
                yoko.append(j+1)
        yoko = [0] + yoko + [H]
        # yoko.append(H)
        # print(yoko)
        
        cut = len(yoko)-2
        lastcut = 0 # index-w
        w = 1
        cannot = False
        while w < W+1:
            if cannot:
                w = W + 100
                break
            for ind, y in enu(yoko):
                if ind == 0:
                    continue
                v1 = cS[y][w]
                v2 = cS[yoko[ind-1]][w]
                v3 = cS[yoko[ind-1]][lastcut]
                v4 = cS[y][lastcut]
                val = v1 - v2 + v3 - v4
                # print('  v1, v2', v1, v2)
                if K < val:
                    cut += 1
                    if lastcut == w-1:
                        cannot = True
                    lastcut = w-1
                    break
            else:
                w += 1
            # print(' val', val)
        if not(cannot) and cut < mcut:
            # print('yoko', yoko)
            mcut = cut

    print(mcut)
if __name__ == '__main__':
    main()