Problem:
 Score : 400 points    Problem Statement There is a grid with N rows and N columns of squares. Let (i,j) be the square at the i -th row from the top and the j -th column from the left.  These squares have to be painted in one of the C colors from Color 1 to Color C . Initially, (i,j) is painted in Color c_{i,j} .  We say the grid is a good grid when the following condition is met for all i,j,x,y satisfying 1 \leq i,j,x,y \leq N :   If (i+j) \% 3=(x+y) \% 3 , the color of (i,j) and the color of (x,y) are the same.  If (i+j) \%  3 \neq (x+y) \% 3 , the color of (i,j) and the color of (x,y) are different.   Here, X \% Y represents X modulo Y .  We will repaint zero or more squares so that the grid will be a good grid.  For a square, the wrongness when the color of the square is X before repainting and Y after repainting, is D_{X,Y} .  Find the minimum possible sum of the wrongness of all the squares.      Constraints  1 \leq N \leq 500  3 \leq C \leq 30  1 \leq D_{i,j} \leq 1000 (i \neq j),D_{i,j}=0 (i=j)  1 \leq c_{i,j} \leq C  All values in input are integers.         Input Input is given from Standard Input in the following format:  N  C  D_{1,1}  ...  D_{1,C}  :  D_{C,1}  ...  D_{C,C}  c_{1,1}  ...  c_{1,N}  :  c_{N,1}  ...  c_{N,N}       Output If the minimum possible sum of the wrongness of all the squares is x , print x .        Sample Input 1 2 3
0 1 1
1 0 1
1 4 0
1 2
3 3      Sample Output 1 3   Repaint (1,1) to Color 2 . The wrongness of (1,1) becomes D_{1,2}=1 .  Repaint (1,2) to Color 3 . The wrongness of (1,2) becomes D_{2,3}=1 .  Repaint (2,2) to Color 1 . The wrongness of (2,2) becomes D_{3,1}=1 .   In this case, the sum of the wrongness of all the squares is 3 .  Note that D_{i,j} \neq D_{j,i} is possible.       Sample Input 2 4 3
0 12 71
81 0 53
14 92 0
1 1 2 1
2 1 1 2
2 2 1 3
1 1 2 2      Sample Output 2 428

Solution (Python):
N,C = map(int,input().split())
D = []
for i in range(C):
    D.append(list(map(int,input().split())))
c = []
for i in range(N):
    c.append(list(map(int,input().split())))

import itertools
current_minimum = 1000 * 500 * 500 + 1
Z = []
Z.append([0]*C)
Z.append([0]*C)
Z.append([0]*C)


for (i,j) in itertools.product(range(N),range(N)):
	cur_mod = ((i+1)+(j+1)) % 3
	cur_color = c[i][j]
	
	
	Z[cur_mod][cur_color-1] += 1

current_minimum = 1000 * 500 * 500 + 1
for (c0,c1,c2) in itertools.permutations(range(C), 3):
	tmp = 0
	color = [c0,c1,c2]
	for cur_mod in range(3):
		target_color = color[cur_mod]
		for cur_color in range(C):
			tmp += Z[cur_mod][cur_color] * D[cur_color][target_color]
	if current_minimum >= tmp:
		current_minimum = tmp
print(current_minimum)

Solution (Python):
def main():
    N, C = map(int, input().split())
    D = []
    c = []
    for i in range(C):
        D.append(list(map(int, input().split())))
    for i in range(N):
        c.append(list(map(int, input().split())))

    c1 = []
    c2 = []
    c3 = []
    for i in range(N):
        for j in range(N):
            if (i+j)%3==0:
                c1.append(c[i][j])
            elif (i+j)%3==1:
                c2.append(c[i][j])
            else:
                c3.append(c[i][j])
    c1_cost = [0 for _ in range(C)]
    c2_cost = [0 for _ in range(C)]
    c3_cost = [0 for _ in range(C)]
    for i in range(C):
        for cc in c1:
            c1_cost[i] += D[cc-1][i]
        for cc in c2:
            c2_cost[i] += D[cc-1][i]
        for cc in c3:
            c3_cost[i] += D[cc-1][i]
    cost = []
    for i in range(C):
        for j in range(C):
            if i!=j:
                for k in range(C):
                    if j!=k!=i:
                        cost.append(c1_cost[i]+c2_cost[j]+c3_cost[k])
    return min(cost)

if __name__=="__main__":
    print(main())

Solution (Python):
from collections import defaultdict
N,C = map(int,input().split())
D=[[int(i) for i in input().split()] for j in range(C)]
co=[[int(i) for i in input().split()] for j in range(N)]
d0= defaultdict(int)
d1= defaultdict(int)
d2= defaultdict(int)
for i in range(N):
    for j in range(N):
        if (j+i) %3==0:
            d0[co[j][i]] +=1
        elif (j+i)%3==1:
            d1[co[j][i]] +=1
        else:
            d2[co[j][i]] +=1
A0=[]
A1=[]
A2=[]
for i in range(C):
    iwa =0
    for s in d0.keys():
        iwa += D[s-1][i-1]*d0[s] 
    A0.append([iwa,i])
for i in range(C):
    iwa =0
    for s in d1.keys():
        iwa += D[s-1][i-1]*d1[s] 
    A1.append([iwa,i])
for i in range(C):
    iwa =0
    for s in d2.keys():
        iwa += D[s-1][i-1]*d2[s] 
    A2.append([iwa,i])

A0.sort()
A1.sort()
A2.sort()
B=[[] for i in range(3)]
for i in range(3):
    B[0].append(A0[i])
for i in range(3):
    B[1].append(A1[i])
for i in range(3):
    B[2].append(A2[i])
ans =[]
for i in range(3):
    for j in range(3):
        for k in range(3):
            if B[0][i][1] ==B[1][j][1]:
                continue
            if B[0][i][1] ==B[2][k][1]:
                continue
            if B[1][j][1] ==B[2][k][1]:
                continue
            ans.append(B[0][i][0]+B[1][j][0]+B[2][k][0])
print(min(ans))

Solution (Python):
from itertools import product,permutations

N,C = map(int,input().split())
D = tuple(tuple(map(int,input().split())) for _ in range(C))
grid = tuple(tuple(map(int,input().split())) for _ in range(N))

cnt = [[0]*C for _ in range(3)]
for x,y in product(range(N),range(N)):
  cnt[(x+y)%3][grid[x][y]-1] += 1

print(min(sum(n*D[i][j] for s,j in zip(range(3),p) for i,n in enumerate(cnt[s])) for p in permutations(range(C), r=3)))

Solution (Python):
N, C = map(int, input().split())
D = [list(map(int, input().split())) for i in range(C)]
line1 = [0]*C
line2 = [0]*C
line0 = [0]*C
for i in range(N):
  c = list(map(int, input().split()))
  for j in range(N):
    if (i+j)%3 == 0:
      line0[c[j]-1] +=+1
    if (i+j)%3 == 1:
      line1[c[j]-1] +=+1
    if (i+j)%3 == 2:
      line2[c[j]-1] +=+1
ans = float("inf")


for i in range(C):
  for j in range(C):
    if j !=i :
      for k in range(C):
        if k !=i and k!=j: 

          curr = 0
          for l in range(C):
            curr += line0[l]*D[l][i]
            curr += line1[l]*D[l][j]
            curr += line2[l]*D[l][k]

          ans = min(ans, curr)
print(ans)

Solution (Python):
N, C = map(int, input().split())
D = [list(map(int, input().split())) for i in range(C)]
line1 = [0]*C
line2 = [0]*C
line0 = [0]*C
for i in range(N):
  c = list(map(int, input().split()))
  for j in range(N):
    if (i+j)%3 == 0:
      line0[c[j]-1] +=+1
    if (i+j)%3 == 1:
      line1[c[j]-1] +=+1
    if (i+j)%3 == 2:
      line2[c[j]-1] +=+1
ans = float("inf")


for i in range(C):
  for j in range(C):
    if j !=i :
      for k in range(C):
        if k !=i and k!=j: 

          curr = 0
          for l in range(C):
            curr += line0[l]*D[l][i]
            curr += line1[l]*D[l][j]
            curr += line2[l]*D[l][k]

          ans = min(ans, curr)
print(ans)

Solution (Python):
import numpy as np
from itertools import permutations


n, c = map(int, input().split())

dd = [list(map(int, input().split())) for _ in range(c)]
cc = [list(map(int, input().split())) for _ in range(n)]

dd = np.array(dd)
cc = np.array(cc)

mod_list = np.zeros((3, c), dtype=np.int)

for i in range(n):
  for j in range(n):
    mod_list[(i+j)%3, cc[i,j]-1] += 1

iwakan_list = mod_list.dot(dd)
  
x = float('inf')
for i, j, k in permutations(range(c), 3):
  x = min(x, iwakan_list[0, i] + iwakan_list[1, j] + iwakan_list[2, k])
print(x)

Solution (Python):
N,C = map(int,input().split())
D = []
for i in range(C):
    d = list(map(int,input().split()))
    D.append(d)
A = []
for i in range(N):
    a = list(map(int,input().split()))
    A.append(a)

X0,X1,X2 = [],[],[]
for i in range(N):
    for j in range(N):
        if (i+j)%3 == 0:
            X0.append(A[i][j])
        elif (i+j)%3 == 1:
            X1.append(A[i][j])
        else:
            X2.append(A[i][j])


Xn = [X0,X1,X2]
cost = [[0 for _ in range(C)] for _ in range(3)]
for i in range(3):
    for c in range(1,C+1):
        Ans = 0
        for x in Xn[i]:
            if x != c:
                Ans += D[x-1][c-1]
        cost[i][c-1] = Ans

Y0 = cost[0]
Y1 = cost[1]
Y2 = cost[2]
Ans = 1000000000000000
for i in range(C):
    for j in range(C):
        for k in range(C):
            if i != j and j != k and k != i:
                Ans = min(Ans, Y0[i]+Y1[j]+Y2[k])

print(Ans)

Solution (Python):
N, C = [int(_) for _ in input().split()]
D = [[int(_) for _ in input().split()] for i in range(C)]
c = [[int(_) - 1 for _ in input().split()] for i in range(N)]

xs = [[], [], []]

for i, row in enumerate(c):
    for j, x in enumerate(row):
        xs[(i + j) % 3].append(x)

cs = [[sum(D[x][j] for x in xs[i]) for j in range(C)] for i in range(3)]

result = 1000000000000000000000000

for c1 in range(C):
    for c2 in range(C):
        if c2 == c1:
            continue
        for c3 in range(C):
            if c3 == c1 or c3 == c2:
                continue
            r = cs[0][c1] + cs[1][c2] + cs[2][c3]
            result = min(result, r)
    
print(result)

Solution (Python):

N,C = map(int,input().split())
D = [list(map(int,input().split())) for i in range(C)]
c = [list(map(int,input().split())) for i in range(N)]

Color = [[0 for i in range(C)] for j in range(3)]

for x in range(N):
	for y in range(N):
		Color[(x+y+2)%3][c[x][y]-1] += 1

ans = 1145141919810
for i in range(C):
	for j in range(C):
		if j == i:
			continue
		for k in range(C):
			if k == i or k == j:
				continue
			tmp = 0
			for x in range(3):
				for y in range(C):
					if x == 0:
						tmp += Color[x][y]*D[y][i]
					elif x == 1:
						tmp += Color[x][y]*D[y][j]
					else:
						tmp += Color[x][y]*D[y][k]
			ans = min(ans,tmp)
print(ans)

Solution (Python):
from itertools import product,permutations

N,C = map(int,input().split())

D = [tuple(map(int,input().split())) for _ in range(C)]

grid = [tuple(map(lambda x: int(x)-1,input().split())) for _ in range(N)]


cnt = [[0]*C for _ in range(3)]

for x,y in product(range(N),range(N)):
  cnt[(x+y)%3][grid[x][y]] += 1

def it():
  for p in permutations(range(C),r=3):
    yield sum(n*D[i][j] for s,j in zip(range(3),p) for i,n in enumerate(cnt[s]))

print(min(it()))

Solution (Python):
from itertools import permutations

n, c = [int(_) for _ in raw_input().split()]
d = [[int(_) for _ in raw_input().split()] for __ in xrange(c)]
st = [[0] * c for _ in range(3)]
for y in xrange(n):
    for x, g in enumerate(raw_input().split()):
        g = int(g) - 1
        st[(x + y) % 3][g] += 1


ds = [[
    sum(st[m3][oldc] * d[oldc][newc] for oldc in xrange(c))
    for newc in xrange(c)] for m3 in range(3)]

p = None
for c1, c2, c3 in permutations(range(c), 3):
    np = ds[0][c1] + ds[1][c2] + ds[2][c3]
    p = np if p is None else min(np, p)

print p

Solution (Python):


import itertools

N,C=[int(i) for i in input().split()]
D=[[int(i) for i in input().split()] for _ in range(C)]
c=[[int(i)-1 for i in input().split()] for _ in range(N)]

costXY = [[0]*C for _ in range(3)]



for X in range(3):
    for Y in range(C):
        costXY[X][Y] = sum([D[c[i][j]][Y] for i,j in itertools.product(range(N), repeat=2) if (i+j)%3==X])



ans = 1<<31
for i in range(C):
    for j in range(C):
        for k in range(C):
            if i==j or j==k or k==i:
                continue
            p=costXY[0][i] + costXY[1][j] + costXY[2][k]

            ans = min(ans,p)
print(ans)

Solution (Python):
n, c = map(int, input().split())
d = [list(map(int ,input().split())) for _ in range(c)]
C = [list(map(int ,input().split())) for _ in range(n)]

grid = [[0]*c for _ in range(3)]
for i in range(n):
    for j in range(n):
        grid[(i+j)%3][C[j][i]-1] += 1

points = []
for i in range(3):
    row = []
    for color in range(1,1+c):
        x = 0
        for j,m in enumerate(grid[i]):
            x += m*d[j][color-1]
        row.append([x, color])
    points.append(row)

for i in range(3):
    points[i].sort()


ans =1000*n*n
for i in range(27):
    x = points[0][i//9]
    y = points[1][i//3%3]
    z = points[2][i%3]
    if x[1] == y[1] or y[1] == z[1] or z[1] == x[1]:
        continue
    ans = min(ans, x[0]+y[0]+z[0])
print(ans)

Solution (Python):
N, c = map(int, input().split())
D = [[int(i) for i in input().split()] for j in range(c)]
C = [[int(i) for i in input().split()] for j in range(N)]
A = [[0 for i in range(c)] for j in range(3)]
for i in range(N):
    for j in range(N):
        for k in range(c):
            A[(i+j)%3][k] += D[C[i][j]-1][k]

ans = 1e9
for i in range(c):
    for j in range(i):
        for k in range(j):
            for l in range(3):
                ans = min(ans, A[l][i]+A[(l+1)%3][j]+A[(l+2)%3][k],
                          A[l][i]+A[(l-1)%3][j]+A[(l-2)%3][k])
print(ans)

Solution (Python):

from itertools import permutations
from collections import Counter
def inpl(): return list(map(int, input().split()))
N, C = inpl()

D = [inpl() for _ in range(C)]

G = [Counter() for _ in range(3)]
for i in range(1, N+1):
    for j, c in enumerate(inpl(), start=1):
        G[(i+j)%3][c-1] += 1

ans = 10**9
for p, q, r in permutations(range(C), 3):
    tmp = 0
    for c in range(C):
        tmp += (D[c][p] * G[0][c]
              + D[c][q] * G[1][c]
              + D[c][r] * G[2][c])
    ans = min(ans, tmp)

print(ans)

Solution (Python):

from itertools import permutations
from collections import Counter
def inpl(): return list(map(int, input().split()))
N, C = inpl()

D = [inpl() for _ in range(C)]

G = [Counter() for _ in range(3)]
for i in range(1, N+1):
    for j, c in enumerate(inpl(), start=1):
        G[(i+j)%3][c-1] += 1

ans = 10**9
for p, q, r in permutations(range(C), 3):
    tmp = 0
    for c in range(C):
        tmp += (D[c][p] * G[0][c]
              + D[c][q] * G[1][c]
              + D[c][r] * G[2][c])
    ans = min(ans, tmp)

print(ans)

Solution (Python):
n, k = map(int, input().split())
c, d = [0] * n, [0] * k
for i in range(k): d[i] = [int(x) for x in input().split()]
for i in range(n): c[i] = [int(x) - 1 for x in input().split()]
z = {}
def f(k, m):
    if (k, m) in z: return z[(k, m)]
    s = 0
    for i in range(n):
        for j in range(n):
            if (i + j) % 3 == m:
                s += d[c[i][j]][k]
    z[(k, m)] = s
    return s
def g(i, s):
    if i == 3: return 0
    m = None
    for l in range(k):
        if s[l]: continue
        s[l] = True
        r = g(i + 1, s)
        s[l] = False
        if r is None: continue
        r += f(l, i)
        if m is None or r < m: m = r
    return m
print(g(0, [False] * k))

Solution (Python):
import itertools
N,C=map(int,input().split())
D=[[int(i) for i in input().split()] for i in range(C)]
c=[[int(i)-1 for i in input().split()] for i in range(N)]
X=[[] for i in range(3)]
for i in range(N):
    for j in range(N):
        X[(i+j)%3].append(c[i][j])
for i in range(3):
    X[i].sort()
Z=[[0 for i in range(C)] for j in range(3)]
for i in range(3):
    for j in X[i]:
        Z[i][j]+=1

I=[[0 for i in range(C)] for j in range(3)]
for i in range(3):
    for j in range(C):
        for k in range(C):
            I[i][j]+=Z[i][k]*D[k][j]
S=itertools.permutations(range(C),3)
ans=10**9
for sg in S:
    tmp=0
    for i in range(3):
        tmp+=I[i][sg[i]]
    if ans>tmp:
        ans=tmp
print(ans)

Solution (Python):
N, C = map(int, input().split())
D = []
c = []
for _ in range(C):
    D.append(list(map(int, input().split())))
for _ in range(N):
    c.append(list(map(lambda x : int(x) - 1, input().split())))
colors = [[0] * C for _ in range(3)]
for i in range(N):
    for j in range(N):
        colors[(i+j)%3][c[i][j]] += 1

def calc(choice):
    ans = 0
    for i,v in zip(range(3),choice):
        for ind, cnt in enumerate(colors[i]):
            ans += cnt * D[ind][v]
    return ans
def dfs(lst, depth):
    ret = []
    if depth == 3:
        return calc(lst)
    for v in range(C):
        if v not in lst:
            lst.append(v)
            ret.append(dfs(lst, depth + 1))
            lst.pop()
    return min(ret)
print(dfs([], 0))

Solution (Python):


N, C = map(int, input().split())

D = [ list(map(int, input().split())) for _ in range(C) ]
col = [ list(map(int, input().split())) for _ in range(N) ]

ans = 1 << 60
info = [ [0 for j in range(C)] for i in range(3) ]

for i in range(N):
    for j in range(N):
        mod = (i + j) % 3
        info[mod][ col[i][j] - 1 ] += 1

for i in range(C):
    for j in range(C):
        for k in range(C):
            if i == j or j == k or k == i:
                continue

            temp = 0
            lst = [i, j, k]

            for x in range(3):
                for y in range(C):
                    temp += D[y][ lst[x] ] * info[x][y]

            ans = min(ans, temp)
            

print(ans)

Solution (Python):
N, C = map(int, input().split())
D = [list(map(int, input().split())) for i in range(C)]
c = [list(map(int, input().split())) for i in range(N)]
col = [[0]*C for i in range(3)]
for i in range(N):
    ci = c[i]
    for j in range(N):
        cc = col[(i+j)%3]
        dd = D[ci[j]-1]
        for k in range(C):
            cc[k] += dd[k]
ans = 10**18
c0 = col[0]
c1 = col[1]
c2 = col[2]
for i in range(C):
    for j in range(C):
        if i == j:
            continue
        for k in range(C):
            if i == k or j == k:
                continue
            ans = min(ans, c0[i] + c1[j] + c2[k])
print(ans)

Solution (Python):
import math,string,itertools,fractions,heapq,collections,re,array,bisect,sys,random,time,copy,functools

sys.setrecursionlimit(10**7)
inf = 10**20
eps = 1.0 / 10**10
mod = 998244353

def LI(): return [int(x) for x in sys.stdin.readline().split()]
def LI_(): return [int(x)-1 for x in sys.stdin.readline().split()]
def LF(): return [float(x) for x in sys.stdin.readline().split()]
def LS(): return sys.stdin.readline().split()
def I(): return int(sys.stdin.readline())
def F(): return float(sys.stdin.readline())
def S(): return input()
def pf(s): return print(s, flush=True)


def main():
    n,c = LI()
    d = [LI() for _ in range(c)]
    e = [LI() for _ in range(n)]
    a = [[0]*c for _ in range(3)]
    for i in range(n):
        for j in range(n):
            t = (i+j) % 3
            for k in range(c):
                a[t][k] += d[e[i][j]-1][k]
    r = inf
    for i in range(c):
        for j in range(c):
            if i == j:
                continue
            for k in range(c):
                if i == k or j == k:
                    continue
                tr = a[0][i] + a[1][j] + a[2][k]
                if r > tr:
                    r = tr

    return r


print(main())

Solution (Python):
N, C = map(int, input().split())
D = [list(map(int, input().split())) for i in range(C)]
c = [list(map(int, input().split())) for i in range(N)]
col = [[0]*3 for i in range(C)]
for i in range(N):
    for j in range(N):
        p = c[i][j]-1
        for k in range(C):
            col[k][(i+j)%3] += D[p][k]
ans = 10**18
for i in range(C):
    for j in range(C):
        if i == j:
            continue
        for k in range(C):
            if i == k or j == k:
                continue
            ans = min(ans, col[i][0] + col[j][1] + col[k][2])
print(ans)

Solution (Python):
import sys

stdin = sys.stdin

ni = lambda: int(ns())
na = lambda: list(map(int, stdin.readline().split()))
ns = lambda: stdin.readline()

n, u = na()
d = []
for i in range(u):
    d.append(na())

c = []
for i in range(n):
    c.append(na())

for i in range(n):
    for j in range(n):
        c[i][j] -= 1

fs = []
for i in range(u):
    f = [0]*3
    for j in range(n):
        t = j%3
        for k in range(n):
            f[t] += d[c[j][k]][i]
            t += 1
            if t == 3:
                t = 0
    fs.append(f)

ans = 99999999999999999
for i in range(u):
    for j in range(u):
        for k in range(u):
            if i == j or j == k or k == i: continue

            ans = min(ans, fs[i][0] + fs[j][1] + fs[k][2])
print(ans)