https://www.acmicpc.net/problem/17406
import static java.lang.Integer.MAX_VALUE;
import static java.lang.Integer.parseInt;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.StringTokenizer;
public class Main {
static int N, M, K;
static int[][] arr;
static boolean[] visited;
static int[] sequence;
static List<RotationInfo> rotationInfos;
static int minRowSum = MAX_VALUE;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
N = parseInt(st.nextToken());
M = parseInt(st.nextToken());
K = parseInt(st.nextToken());
arr = new int[N][M];
visited = new boolean[K];
sequence = new int[K];
for (int r = 0; r < N; r++) {
st = new StringTokenizer(br.readLine());
for (int c = 0; c < M; c++) {
arr[r][c] = parseInt(st.nextToken());
}
}
rotationInfos = new ArrayList<>();
for (int i = 0; i < K; i++) {
st = new StringTokenizer(br.readLine());
int r = parseInt(st.nextToken()) - 1;
int c = parseInt(st.nextToken()) - 1;
int s = parseInt(st.nextToken());
rotationInfos.add(new RotationInfo(r, c, s));
}
int[][] result = new int[N][M];
deepCopy(arr, result);
dfs(0);
System.out.println(minRowSum);
br.close();
}
static void deepCopy(int[][] arr, int[][] temp) {
for (int r = 0; r < arr.length; r++) {
for (int c = 0; c < arr[r].length; c++) {
temp[r][c] = arr[r][c];
}
}
}
static int getMinRowSum(int[][] arr) {
int value = MAX_VALUE;
for (int r = 0; r < N; r++) {
int sum = Arrays.stream(arr[r]).sum();
value = Math.min(value, sum);
}
return value;
}
static int[][] rotate(int[][] arr, RotationInfo info) {
int[][] temp = new int[N][M];
deepCopy(arr, temp);
for (int s = 1; s <= info.s; s++) {
for (int c = info.c - s; c < info.c + s; c++) {
temp[info.r - s][c + 1] = arr[info.r - s][c];
}
for (int r = info.r - s; r < info.r + s; r++) {
temp[r + 1][info.c + s] = arr[r][info.c + s];
}
for (int c = info.c + s; c > info.c - s; c--) {
temp[info.r + s][c - 1] = arr[info.r + s][c];
}
for (int r = info.r + s; r > info.r - s; r--) {
temp[r - 1][info.c - s] = arr[r][info.c - s];
}
}
return temp;
}
static void dfs(int depth) {
if (depth == K) {
int[][] result = new int[N][M];
deepCopy(arr, result);
for (int i = 0; i < sequence.length; i++) {
result = rotate(result, rotationInfos.get(sequence[i]));
}
minRowSum = Math.min(minRowSum, getMinRowSum(result));
return;
}
for (int i = 0; i < visited.length; i++) {
if (visited[i]) {
continue;
}
visited[i] = true;
sequence[depth] = i;
dfs(depth + 1);
visited[i] = false;
}
}
static class RotationInfo {
int r, c, s;
public RotationInfo(int r, int c, int s) {
this.r = r;
this.c = c;
this.s = s;
}
}
}