from ortools.sat.python import cp_model import sys def main(): input = sys.stdin.readline N, T = map(int, input().split()) A = [list(map(int, input().split())) for _ in range(N)] V = N * N weights = [A[i][j] for i in range(N) for j in range(N)] # 隣接する有向ペア adjacent_pairs = [] for i in range(N): for j in range(N): u = i * N + j for di, dj in [(1, 0), (-1, 0), (0, 1), (0, -1)]: ni, nj = i + di, j + dj if 0 <= ni < N and 0 <= nj < N: v = ni * N + nj adjacent_pairs.append((u, v)) model = cp_model.CpModel() # p[k] = k番目に訪れるマス p = [model.NewIntVar(0, V - 1, f"p[{k}]") for k in range(T)] # 同じマスを二度訪れない model.AddAllDifferent(p) # 連続するマスは隣接 for k in range(T - 1): model.AddAllowedAssignments([p[k], p[k + 1]], adjacent_pairs) # 各ステップの得点 max_a = max(weights) score_vars = [] for k in range(T): s = model.NewIntVar(0, max_a, f"score[{k}]") model.AddElement(p[k], weights, s) score_vars.append(s) model.Maximize(sum(score_vars)) # 初期解ヒント: ジグザグパス hint_path = [] for i in range(N): if i % 2 == 0: for j in range(N): hint_path.append(i * N + j) else: for j in range(N - 1, -1, -1): hint_path.append(i * N + j) for k in range(T): model.AddHint(p[k], hint_path[k]) solver = cp_model.CpSolver() solver.parameters.max_time_in_seconds = 1.8 solver.parameters.num_search_workers = 8 status = solver.Solve(model) if status not in (cp_model.OPTIMAL, cp_model.FEASIBLE): # フォールバック: ジグザグ path = hint_path[:T] else: path = [solver.Value(p[k]) for k in range(T)] print(len(path)) for u in path: print(u // N, u % N) if __name__ == "__main__": main()