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



Sample input:
2 3
0 1 1
1 0 1
1 4 0
1 2
3 3


Sample output:
3

Submission status: Accepted

Solution code:
import copy


input_line = input().split()
grid_size = int(input_line[0])
num_color = int(input_line[1])

differential_cost = {}
for color_from in range(1, num_color + 1):
    input_line = input().split()
    for color_to in range(1, num_color + 1):
        differential_cost[(color_from, color_to)] = int(input_line[color_to-1])

color_map = {}
for x in range(1, grid_size + 1):
    input_line = input().split()
    for y in range(1, grid_size + 1):
        color_map[(x, y)] = int(input_line[y-1])

current_color_dict = {}
for color in range(1, num_color+1):
    current_color_dict[color] = 0

current_color_mod0 = copy.deepcopy(current_color_dict)
current_color_mod1 = copy.deepcopy(current_color_dict)
current_color_mod2 = copy.deepcopy(current_color_dict)

for index, color in color_map.items():
    x, y = index
    if (x + y) % 3 == 0:
        current_color_mod0[color] += 1
    elif (x + y) % 3 == 1:
        current_color_mod1[color] += 1
    elif (x + y) % 3 == 2:
        current_color_mod2[color] += 1

combinations = [(color_mod0, color_mod1, color_mod2)
                for color_mod0 in range(1, num_color+1)
                for color_mod1 in range(1, num_color+1)
                for color_mod2 in range(1, num_color+1)]

cost_list = []
for combination in combinations:
    color_mod0, color_mod1, color_mod2 = combination
    if color_mod0 == color_mod1 or color_mod0 == color_mod2 or color_mod1 == color_mod2:
        continue

    cost = 0
    for color_from in range(1, num_color+1):
        cost += differential_cost[(color_from, color_mod0)] * current_color_mod0[color_from]
        cost += differential_cost[(color_from, color_mod1)] * current_color_mod1[color_from]
        cost += differential_cost[(color_from, color_mod2)] * current_color_mod2[color_from]

    cost_list.append(cost)

print(str(min(cost_list)))

Submission status: Accepted

Solution code:
import itertools
import functools

def inp():
  return list(map(int, input().split()))

N,C = inp()
D = [[0] * (C+1)]
c = [[], [], []]
for i in range(C):
  D.append([0] + inp())
for i in range(N):
  l = inp()
  for j in range(N):
    c[(i+j)%3].append(l[j])

# print(N,C,D,c)

sc = list(itertools.permutations(list(range(1,C+1)), 3))
# print(sc)

ret = []
for i in range(3):
  ret.append([])
  for j in range(1,C+1):    
    ret[-1].append(sum(list(map(lambda x: D[x][j], c[i]))))
#  print(ret[-1])

ans = []
for sc_i in sc:
  ans.append(0)
  for i in range(3):
    ans[-1] += ret[i][sc_i[i]-1]
#  print(ans[-1])

print(min(ans))

Submission status: Accepted

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

res = [[0] * C for i in range(3)]
for i in range(N):
  for j in range(N):
    res[(i+j)%3][c[i][j]-1] += 1
small = 250000000
for i in range(C):
  for j in range(C):
    for k in range(C):
      if i == j or i == k or j == k:
        continue
      total = 0
      for m in range(C):
          total += res[0][m] * D[m][i]
          total += res[1][m] * D[m][j]
          total += res[2][m] * D[m][k]
      if total < small:
        small = total
print(small)

Submission status: Accepted

Solution code:
import numpy as np
N, C = map(int, input().split())
D = np.array(list(map(int, input().split())), dtype=int)
for i in range(C-1):
    D = np.vstack((D, np.array(list(map(int, input().split())), dtype=int)))
Z = np.array(list(map(int, input().split())), dtype=int)
for i in range(N-1):
    Z = np.vstack((Z, np.array(list(map(int, input().split())), dtype=int)))
num = np.zeros((3,C), dtype=int)
for i in range(3):
    X = np.array([[(x+y+2)%3==i for y in range(N)] for x in range(N)])
    for c in range(C):
        Y = ((Z*X)==(c+1))
        num[i,c] = Y.sum()
costs = np.dot(num, D)
mincost = 10**10
for c0 in range(C):
    for c1 in range(C):
        if c1 ==c0:
            continue
        for c2 in range(C):
            if c2 == c0 or c2 == c1:
                continue
            cost = costs[0,c0]+costs[1,c1]+costs[2,c2]
            mincost = min(mincost, cost)
print(mincost)

Submission status: Accepted

Solution code:
N,C=map(int,input().split())
s=[list(map(int,input().split())) for i in range(C)]
t=[[0]*C for i in range(3)]
ll,kk=[],[[0]*C for i in range(3)]
for k in range(N):
    for i,j in enumerate(list(map(int,input().split()))):
        t[(i+k)%3][j-1]+=1
for j in range(3):
    for i in range(C):
        for k in range(C):
            kk[j][k]+=(s[i][k]*t[j][i])
from itertools import permutations
ans=10**9
for i,j,k in permutations(range(C),3):
    p=kk[0][i]+kk[1][j]+kk[2][k]
    ans=min(ans,kk[0][i]+kk[1][j]+kk[2][k])
print(ans)

Submission status: Accepted

Solution code:
import numpy as np
ans=10**9
N,C=map(int,input().split())
s=[list(map(int,input().split())) for i in range(C)]
t=[list(map(int,input().split())) for i in range(N)]
u=[np.zeros((C)) for i in range(3)]
for i in range(N):
    for j in range(N):
        u[(i+j)%3]+=np.array(s[t[i][j]-1])
from itertools import permutations
for i,j,k in list(permutations(range(C),3)):
    p=u[0][i]+u[1][j]+u[2][k]
    ans=min(ans,p)
print(int(ans))

Submission status: Accepted

Solution code:
import numpy as np
N,C=map(int,input().split())
ans=10**9
a=np.array([0]*C)
b=np.array([0]*C)
c=np.array([0]*C)
s=[]
t=[]
for i in range(C):
    s.append(list(map(int,input().split())))
for i in range(N):
    t.append(list(map(int,input().split())))
for j in range(N):
    for i in range(N):
        if (i+j)%3==0:
            a+=np.array(s[t[i][j]-1])
        elif (i+j)%3==1:
            b+=np.array(s[t[i][j]-1])
        else:
            c+=np.array(s[t[i][j]-1])
from itertools import permutations
for i,j,k in permutations(range(C),3):
    p=a[i]+b[j]+c[k]
    ans=min(p,ans)
print(ans)

Submission status: Accepted

Solution code:
N,C=map(int,input().split(' '))
D=[]
for _ in range(C):
  D.append([ x for x in map(int,input().split(' '))])

c=[]
for _ in range(N):
  c.append([ x for x in map(int,input().split(' '))])

x=float('inf')

memo={}

counter=[[0]*C for _ in range(3)]
for i in range(N):
  for j in range(N):
    b=i%3
    cur=c[i][j]
    counter[(j+b)%3][cur-1]+=1
    #s+=D[cur-1][seq[(j+b)%3]]

for c0 in range(C):
  for c1 in range(C):
    if c1==c0:
      continue
    for c2 in range(C):
      if c2==c0 or c2==c1:
        continue
      s=0
      for i, cx in enumerate(counter[0]):
        s+=D[i][c0]*cx
      for i, cx in enumerate(counter[1]):
        s+=D[i][c1]*cx
      for i, cx in enumerate(counter[2]):
        s+=D[i][c2]*cx
      if s<x:
        x=s


print(x)

Submission status: Accepted

Solution code:
import numpy as np                                                                                                                                                    
if __name__ == '__main__':
    N, C = map(int, input().split(' '))
    D = []
    for i in range(C):
        D.append(list(map(int, input().split(' '))))

    field = []
    for i in range(N):
        field.append(list(map(int, input().split(' '))))
    field = np.array(field) - 1

    res0 = {}
    res1 = {}
    res2 = {}
    for i in range(N):
        for j in range(N):
            if (i + j) % 3 == 0:
                if field[i][j] in res0.keys():
                    res0[field[i][j]] += 1
                else:
                    res0[field[i][j]] = 1
            if (i + j) % 3 == 1:
                if field[i][j] in res1.keys():
                    res1[field[i][j]] += 1
                else:
                    res1[field[i][j]] = 1
            if (i + j) % 3 == 2:
                if field[i][j] in res2.keys():
                    res2[field[i][j]] += 1
                else:
                    res2[field[i][j]] = 1

    res = 1e+10
    #iはあまり0のマスの色
    for i in range(C):
        #jはあまり0のマスの色
        for j in range(C):
            if i == j:
                continue
            #kはあまり0のマスの色
            for k in range(C):
                if i == k or j == k:
                    continue
                temp = 0
                for color in res0.keys():
                    temp += D[color][i] * res0[color]
                for color in res1.keys():
                    temp += D[color][j] * res1[color]
                for color in res2.keys():
                    temp += D[color][k] * res2[color]
                if temp < res:
                    res = temp
    print(res)

Submission status: Accepted

Solution code:
# import time
N, C = map(int, input().split())              # 同上。map関数を使うとこのように書ける

D = [[0 for i in range(C)] for j in range(C)]
c = [[0 for i in range(N)] for j in range(N)]
# iwakan = [[[0 for i in range(N)] for j in range(N)] for k in range(C)]

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

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

# まず違和感リストを作る。
# for i in range(C):
#     for j in range(N):
#         for k in range(N):
#             iwakan[i][j][k] = D[c[j][k] - 1][i]

'''
Gij0 : (i + j) % 3 == 0 となる場所
Gij1 : (i + j) % 3 == 1 となる場所
Gij2 : (i + j) % 3 == 2 となる場所
とした時に、
Gijnに属する場所全ての色をaに塗り替える場合の違和感の合計を
iwakan[n][a]とする。
iwakan[n][a]を全て求めるための計算量は、30*500*500 = 7500000
iwakan を用いて全ての色の塗り替えの組み合わせを求めるための計算量は
30 * 29 * 28 = 24360
'''

# t1 = time.time()

# Gijnに属する色の数を合計したリストを作る。
numOfColors = [[0 for i in range(C)] for j in range(3)]
for i in range(N):
    for j in range(N):
        if (i + j) % 3 == 0:
            numOfColors[0][c[i][j] - 1] = numOfColors[0][c[i][j] - 1] + 1
        if (i + j) % 3 == 1:
            numOfColors[1][c[i][j] - 1] = numOfColors[1][c[i][j] - 1] + 1
        if (i + j) % 3 == 2:
            numOfColors[2][c[i][j] - 1] = numOfColors[2][c[i][j] - 1] + 1

iwakan = [[0 for i in range(C)] for j in range(3)]
for i in range(3):
    for j in range(C):
        for a in range(C):
            iwakan[i][j] = iwakan[i][j] + numOfColors[i][a] * D[a][j]

# t2 = time.time()

sum_min = float("inf")
for i in range(C):
    for j in range(C):
        for k in range(C):
            if (i == j) or (j == k) or (k == i):
                pass
            else:
                sum_tmp = iwakan[0][i] + iwakan[1][j] + iwakan[2][k]
                if sum_min > sum_tmp:
                    sum_min = sum_tmp

# t3 = time.time()

print(sum_min)

# elapsed_time1 = t2 - t1
# elapsed_time2 = t3 - t2
# print(f'time1: {elapsed_time1}')
# print(f'time2: {elapsed_time2}')

Submission status: Accepted

Solution code:
import itertools

N, C = map(int, input().split())
# N, C = 500, 30

D = []
for _ in range(C):
    D.append(list(map(int, input().split())))
    # D.append([100] * C)

diff_by_pos_color_pair = [[0 for _ in range(C)] for _ in range(3)]
for i in range(N):
    for j, color_from in enumerate(map(lambda x: int(x) - 1, input().split())):
        # for j, color_from in enumerate([0] * N):
        pos = (i + j) % 3
        for color_to in range(C):
            diff_by_pos_color_pair[pos][color_to] += D[color_from][color_to]


min_diff = float("inf")
for ccs in itertools.permutations(range(C), 3):
    diff = 0
    for pos, color in enumerate(ccs):
        diff += diff_by_pos_color_pair[pos][color]
    min_diff = min(min_diff, diff)

print(min_diff)

Submission status: Accepted

Solution code:
N, C = map(int, input().split())
D = [list(map(int, input().split())) for k in range(C)]
G = [list(map(int, input().split())) for k in range(N)]

M = [[0,0,0] for k in range(C)]
for x in range(N):
    for y in range(N):
        M[G[x][y]-1][(x+y)%3] += 1

ans = 10**9
for p in range(C):
    for q in range(C):
        for r in range(C):
            if p!=q and q!=r and r!=p:
                t = 0
                for s in range(C):
                    t += D[s][p]*M[s][0]+ D[s][q]*M[s][1] + D[s][r]*M[s][2]
                ans = min(t,ans)

print(ans)

Submission status: Accepted

Solution code:
from pprint import pprint

# --- データ読み込み ---
N, C = [int(i) for i in input().split()]
D_xy = []
for _ in range(C):
    D_xy.append([int(i) for i in input().split()])
c_ij = []
for _ in range(N):
    c_ij.append([int(i) for i in input().split()])

# --- 読み込み結果確認 ---
# pprint(D_xy)
# pprint(c_ij)

# --- 各クラスタに分類 ---
clusters = [[] for _ in range(3)]
for i in range(N):
    for j in range(N):
         if (i+j) % 3 == 0:
             clusters[0].append(c_ij[i][j])
         elif (i+j) % 3 == 1:
             clusters[1].append(c_ij[i][j])
         elif (i+j) % 3 == 2:
             clusters[2].append(c_ij[i][j])
         else:
             # print(i+j % 3) # % の前は()でくくらないと順番が狂う
             # print("Something wrong")
             pass

# まずは，各クラスタをある色にするために必要なコストを計算する
# つまり， clusters[i] to c の距離を予め計算する
cost_matrix = [[0 for _ in range(C)] for _ in range(3)]
# print(cost_matrix)
for i in range(3):
    for c in range(C):
        cost = 0
        for item in clusters[i]:
            cost += D_xy[item-1][c] # item-1 が index に対応
        # print(i,c)
        cost_matrix[i][c] = cost

# print("cost_matrix")
# pprint(cost_matrix)

## cost_matrixの中から一番賢い組み合わせを選択する
min = float('infinity')
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
            score = cost_matrix[0][i] + cost_matrix[1][j] + cost_matrix[2][k]
            # print(i,j,k,"score:",score)
            if score < min:
                min = score
print(min)

Submission status: Accepted

Solution code:
#!/usr/bin/env python3
import sys
def debug(*args): print(*args, file=sys.stderr)
def exit(): sys.exit(0)

N, C = map(int, input().split())
D = []
col = []

for c in range(C):
    Drow = list(map(int, input().split()))
    D.append(Drow)
for i in range(N):
    crow = list(map(int, input().split()))
    crow = list(map(lambda x: x-1,
                    crow))
    col.append(crow)

#
count = [[0]*C for m in range(3)]

for i in range(N):
    for j in range(N):
        m = (i + j) % 3
        count[m][col[i][j]] += 1

def iwakan(y):
    res = 0
    for m in range(3):
        for c in range(C):
            res += D[c][y[m]] * count[m][c]
    return res

iwakan_list = []
for c1 in range(C):
    for c2 in range(C):
        if c1 == c2:
            continue
        for c3 in range(C):
            if (c3 == c1) or (c3 == c2):
                continue
            y = [c1, c2, c3]
            debug(y, iwakan(y))
            iwakan_list.append(iwakan(y))

print(min(iwakan_list))

Submission status: Accepted

Solution code:
N, C = map(int, input().split())
D = [0] + [[0]+list(map(int, input().split())) for _ in range(C)]

ct = [{}, {}, {}]

for i in range(1, N+1):
  for j, c in enumerate(list(map(int, input().split()))):
    k = (i+j+1) % 3
    ct[k][c] = ct[k].get(c, 0) + 1

ans = float('inf')
for c1 in range(1, C+1):
  d1 = 0
  for c, v in ct[0].items():
    if c != c1:
      d1 += D[c][c1] * v
  for c2 in range(1, C+1):
    if c1 == c2:
      continue
    d2 = 0
    for c, v in ct[1].items():
      if c != c2:
        d2 += D[c][c2] * v
    for c3 in range(1, C+1):
      if c1 == c3 or c2 == c3:
        continue
      d3 = 0
      for c, v in ct[2].items():
        if c != c3:
          d3 += D[c][c3] * v
      ans = min(ans, d1+d2+d3)

print(ans)

Submission status: Accepted

Solution code:
def main():
    n, c = map(int, input().split())
    d = [list(map(int, input().split())) for i in range(c)]
    grid = [list(map(int, input().split())) for i in range(n)]

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

    min_cost = 1 << 30
    for i in range(c):
        for j in range(c):
            if i != j:
                for k in range(c):
                    if j != k and k != i:
                        cost = 0
                        for color in range(c):
                            cost += group[0][color] * d[color][i]
                            cost += group[1][color] * d[color][j]
                            cost += group[2][color] * d[color][k]

                        min_cost = min(cost, min_cost)

    print(min_cost)


if __name__ == '__main__':
    main()

Submission status: Accepted

Solution code:
from collections import Counter
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)]

ls = [Counter ([c[i][j] for i in range(N) for j in range(N) if (i+j)%3 == k]) for k in range(3)]

result = float("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
            tt = 0
            for l in range(1,C+1):
                tt += ls[0][l] * D[l-1][i]
                tt += ls[1][l] * D[l-1][j]
                tt += ls[2][l] * D[l-1][k]
            result = min(tt, result)
 
print(result)

Submission status: Accepted

Solution code:
n, c = [int(i) for i in 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)]

# for i in range(c):
#   for j in range(c):
#     for k in range(c):
#       d = D[i][j] + D[j][k]
#       if D[i][k] > d:
#         D[i][k] = d

sum_d = [[0] * c for i in range(3)]
mod_c = [[0] * c for i in range(3)]

for i in range(n):
  for j in range(n):
      mod_c[(i+j)%3][C[i][j]-1] += 1

for i in range(c):
    for j in range(c):
        for k in range(3):
            sum_d[k][j] += D[i][j] * mod_c[k][i]
      
max_d = 1000 * (n//3+1)
ans = max_d * n**2
      
for i in range(c):
  for j in range(c):
    for k in range(c):
      if i != j != k != i:
        ans = min(ans, sum_d[0][i] + sum_d[1][j] + sum_d[2][k])
        
print(ans)

Submission status: Accepted

Solution code:
from itertools import permutations
N, C = map(int, input().split())
D = []
for i in range(C):
    D.append([int(i) for i in input().split()])
c = []
for i in range(N):
    c.append([int(i) for i in input().split()])

counter = {i: {} for i in range(3)}
for i in range(N):
    for j in range(N):
        m = (i+j) % 3
        color = c[i][j] - 1
        if counter[m].get(color) is None: counter[m][color] = 0
        counter[m][color] += 1

ans = float('inf')

for i,j,k in permutations(range(C), 3):
    tmp = 0
    for l in range(C):
        tmp += D[l][i] * counter[0].get(l, 0)
        tmp += D[l][j] * counter[1].get(l, 0)
        tmp += D[l][k] * counter[2].get(l, 0)
    ans = min(tmp, ans)

print(ans)

Submission status: Accepted

Solution code:
N, C = map(int, input().split())
D = [list(map(int, input().split())) for _ in range(C)]
c_ = [[0 for _ in range(C)] for _ in range(3)]
for i in range(N):
  ci =list(map(int, input().split()))
  for j in range(N):
    cij = ci[j]
    c_[(i+j)%3][cij-1] += 1

cost = [[0 for _ in range(C)] for _ in range(3)]
for i in range(3):
  for j in range(C):
    for k in range(C):
      cost[i][k] += D[j][k] * c_[i][j]
      
ans = 1000*500*500
for i in range(C):
  if ans < cost[0][i]:
    continue
  for j in range(C):
    if i is j:
      continue
    if ans < (cost[0][i]+cost[1][j]):
      continue
    for k in range(C):
      if i is k or j is k:
      	continue
      ans = min(ans, cost[0][i]+cost[1][j]+cost[2][k])
print(ans)

Submission status: Accepted

Solution code:
N,C=[int(x) for x in str(input()).split()]
D=[[0 for x in range(0,C+1)]]
for i in range (0,C):
  D.append([0]+[int(x) for x in str(input()).split()])
c=[[0 for x in range(0,N+1)]]
for j in range(0,N):
  c.append([0]+[int(x) for x in str(input()).split()])



mod1=[0 for x in range(0,C+1)]
mod2=[0 for x in range(0,C+1)]
mod0=[0 for x in range(0,C+1)]

for x in range (1,N+1):
  for y in range(1,N+1):
    if (x+y)%3==0:
      mod0[c[x][y]]+=1
    elif (x+y)%3==1:
      mod1[c[x][y]]+=1
    else:
      mod2[c[x][y]]+=1



error=1000000000
for i in range(1,C+1):
  for j in range(1,C+1):
    if j!=i:
      for k in range(1,C+1):
        if k!=j:
          if k!=i:
            e=0

            for x in range(1,C+1):
              e+=mod0[x]*D[x][i]+mod1[x]*D[x][j]+mod2[x]*D[x][k]


       
            error=min(error,e)
print(error)

Submission status: Accepted

Solution code:
from itertools import permutations, product

def main():
    N, C = map(int, input().split())
    Dc = [tuple(map(int, input().split())) for _ in [0] * C]
    Cn = [tuple(map(int, input().split())) for _ in [0] * N]

    sum_ = [[0] * C for _ in [0] * 3]
    for i, j in product(range(N), repeat=2):
        c = Cn[i][j] - 1
        n = (i + j) % 3
        for k in range(C):
            sum_[n][k] += Dc[c][k]

    cost = float('inf')
    for i, j, k in permutations(range(C), 3):
        cost = min(cost, sum_[0][i] + sum_[1][j] + sum_[2][k])
    print(cost)

main()

Submission status: Accepted

Solution code:
from itertools import permutations

def main():
    N, C = map(int, input().split())
    Dc = [tuple(map(int, input().split())) for _ in [0] * C]
    Cn = [tuple(map(int, input().split())) for _ in [0] * N]

    sum_ = [[0] * C for _ in [0] * 3]
    for i, cn in enumerate(Cn):
        for j, c in enumerate(cn):
            n = (i + j) % 3
            for k in range(C):
                sum_[n][k] += Dc[c-1][k]

    cost = float('inf')
    for i, j, k in permutations(range(C), 3):
        cost = min(cost, sum_[0][i] + sum_[1][j] + sum_[2][k])
    print(cost)

main()

Submission status: Accepted

Solution code:
N, C = map(int, input().split())
d = []
c = []
t = [[0]*C, [0]*C, [0]*C]
for _ in range(C):
  d.append(list(map(int, input().split())))
for _ in range(N):
  c.append(list(map(int, input().split())))

for i in range(N):
  for j in range(N):
    t[(i+j)%3][c[i][j]-1] += 1

ans=1000*N*N

for i in range(C):
  for j in range(C):
    if i!=j:
      for k in range(C):
        if i!=k and j!=k:
          tt=0
          for l in range(C):
            tt += d[l][i]*t[0][l] + d[l][j]*t[1][l]+d[l][k]*t[2][l]
          ans = min(ans, tt)
print(ans)

Submission status: Accepted

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

colorBucket=[[0]*C, [0]*C, [0]*C]
for i in range(1,N+1):
    for j in range(1,N+1):
        colorBucket[(i+j)%3][gridColor[i-1][j-1]-1] += 1

cost_change_color=[[0]*C, [0]*C, [0]*C]

for k in range(3):
#グループごとに、ある色への塗り替えコストの計算
    for m in range(C):
        total=0
        for l in range(C):
            total+=D[l][m]*colorBucket[k][l]
        cost_change_color[k][m] = total

cost = []
for s in range(C):
    for t in range(C):
        for r in range(C):
            if not(s==t or t==r or r==s):
                cost.append(cost_change_color[0][s]+cost_change_color[1][t]+cost_change_color[2][r])

print(min(cost))

Submission status: Accepted

Solution code:
#次のコードを改変した
#https://abc099.contest.atcoder.jp/submissions/2657877
    #リストの内包表記を自分でも分かる書き方に直した
from itertools import product
from collections import Counter

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

res = []
for r in range(3):
    color_count = Counter(matrix[i][j] - 1 for i in range(n) for j in range(n) if (i + j) % 3 == r)

    def color_cost(color):
        return sum(color_costs[ccolor][color] * ccount for ccolor, ccount in color_count.items())
    cx = [(color, color_cost(color)) for color in range(c)]
    sorted_by_cost = sorted(cx, key=lambda x:x[1])
    cheapest3 = sorted_by_cost[:3]
    res.append(cheapest3)

#print(res)
color_pickss = product(*res)
#for picks in color_pickss:
#    print(picks)
filtered_unique = (picks for picks in color_pickss if len(set(color for color, _ in picks)) == 3)
costs = (sum(cost for _, cost in picks) for picks in filtered_unique)
print(min(costs))

Submission status: Accepted

Solution code:
def main():
    N, C = map(int, input().split())
    D = []
    for i in range(C):
        D.append(list(map(int, input().split())))
        
    c_init = []
    for i in range(N):
        c_init.append(list(map(int,input().split())))
    
    group0 = [0]*C
    group1 = [0]*C
    group2 = [0]*C
    
    
    #1. 各グループに何色がどれだけあるかチェック
    for i in range(N):
        for j in range(N):
            if (i+j+2)%3==0:
                group0[c_init[i][j] - 1] += 1
            elif (i+j+2)%3 == 1:
                group1[c_init[i][j] - 1] += 1
            else:
                group2[c_init[i][j] - 1] += 1
    
    #2. 違和感の大きさをチェック
    iwakan =[]
    for color0 in range(C):
        for color1 in range(C):
            if color1 == color0:
                continue
            
            for color2 in range(C):
                if color2==color0 or color2==color1:
                    continue
                
                iwakan_temp = 0
                for colorN in range(C):
                    iwakan_temp += group0[colorN]*D[colorN][color0]
                    iwakan_temp += group1[colorN]*D[colorN][color1]
                    iwakan_temp += group2[colorN]*D[colorN][color2]
                
                iwakan.append(iwakan_temp)
                
    print(min(iwakan))
    
if __name__ == "__main__":
    main()

Submission status: Accepted

Solution code:
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
#iwakan
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)

Submission status: Accepted

Solution code:
import itertools
N,C=map(int, input().split())
D=[list(map(int, input().split())) for _ in range(C)]
cl_cnt=[[0 for _ in range(C) ] for _ in range(3)]
for i in range(N):
    ci=list(map(int, input().split()))
    for j, cij in enumerate(ci):
        cl_cnt[(i+j)%3][cij-1]+=1 

cost=[[0 for _ in range(C) ] for _ in range(3)]
for i in range(3):
    for j in range(C):
        for k in range(C):
            cost[i][k]+=(D[j][k])*cl_cnt[i][j]

ans=1000*500*500
for i, j, k in itertools.permutations(range(C),3):
    ans=min(cost[0][i]+cost[1][j]+cost[2][k], ans)
print(ans)

Submission status: Accepted

Solution code:
N,C=map(int, input().split())
D=[list(map(int, input().split())) for _ in range(C)]
clr=[[0 for _ in range(C) ] for _ in range(3)]
cost=[[0 for _ in range(C) ] for _ in range(3)]

for i in range(N):
    ci=list(map(int, input().split()))
    for j, cij in enumerate(ci):
        clr[(i+j)%3][cij-1]+=1 

for i in range(3):
    for j in range(C):
        for k in range(C):
            cost[i][k]+=(D[j][k])*clr[i][j]

ans=1000*500*500
for i in range(C):
    for j in filter(lambda x:x!=i,range(C)):
        for k in filter(lambda x:x!=i and x!=j, range(C)):
            #print(cost[0][i]+cost[1][j]+cost[2][k])
            ans=min(cost[0][i]+cost[1][j]+cost[2][k], ans)
print(ans)

Submission status: Accepted

Solution code:
import numpy as np

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

zero_cnt_list = [0 for i in range(c)]
one_cnt_list = [0 for i in range(c)]
two_cnt_list = [0 for i in range(c)]

for i in range(n):
    for j in range(n):
        if ((i+1)+(j+1)) % 3 == 0:
            zero_cnt_list[c_mat[i][j] - 1] += 1
        elif ((i+1)+(j+1)) % 3 == 1:
            one_cnt_list[c_mat[i][j] - 1] += 1
        elif ((i+1)+(j+1)) % 3 == 2:
            two_cnt_list[c_mat[i][j] - 1] += 1

cost_list = []
for i in range(c):
    zero_cost = sum(np.array(zero_cnt_list) * np.array([d_mat[l][i] for l in range(c)]))
    for j in range(c):
        if j == i:
            continue
        one_cost = sum(np.array(one_cnt_list) * np.array([d_mat[l][j] for l in range(c)]))
        for k in range(c):
            if k == i or k == j:
                continue
            two_cost = sum(np.array(two_cnt_list) * np.array([d_mat[l][k] for l in range(c)]))
            cost_list.append(zero_cost + one_cost + two_cost)
print(min(cost_list))

Submission status: Accepted

Solution code:
N, C = map(int, input().split())
#D[X][Y] = (X+1)→(Y+1)に塗り替えたときの違和感
D = [list(map(int, input().split())) for i in range(C)]
#C[i][j] = (i+1,j+1)の色
c = [list(map(int, input().split())) for i in range(N)]
#import pdb; pdb.set_trace()
ans = float('inf')
#c0: (i+1)+(j+1) \equiv 0 なるマスに色1, 色2, ..., 色Cがそれぞれ何個書かれているか
c0 = [0] * C
c1 = [0] * C
c2 = [0] * C
for i in range(N):
    for j in range(N):
        if (i + j) % 3 == 0:
            c0[c[i][j] - 1] += 1
        if (i + j) % 3 == 1:
            c1[c[i][j] - 1] += 1
        if (i + j) % 3 == 2:
            c2[c[i][j] - 1] += 1


for x in range(C):
    for y in range(C):
        for z in range(C):
            if (x-y)*(y-z)*(z-x) != 0:
                iwakan = sum(D[i][x] * c0[i] for i in range(C)) + sum(D[j][y] * c1[j] for j in range(C))+sum(D[k][z] * c2[k] for k in range(C))                
                ans = min(ans, iwakan)
print(ans)