[BOJ 17406] 배열 돌리기4
업데이트:
문제
- BOJ 17406
- 문제의 저작권은 Baekjoon Online Judge에 있습니다.
접근방식
연산 순서에 따라서 결과가 달라지므로 순열로 연산 순서를 결정한다(per())
그리고 시계방향으로 회전시킨값을 tmp
에 임시로 넣어주고 이때의 최소값을 구해서 비교하여 최종 답을 구한다.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class Main {
static int N,M,K,depth;
static int[][] map;
static int[][] kInfo;
static int r,c,s,lx,ly,rx,ry;
static int ans = Integer.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 = Integer.parseInt(st.nextToken());
M = Integer.parseInt(st.nextToken());
K = Integer.parseInt(st.nextToken());
map = new int[N+1][M+1];
for(int i=1; i<=N; i++) {
st = new StringTokenizer(br.readLine());
for(int j=1; j<=M; j++) {
map[i][j] = Integer.parseInt(st.nextToken());
}
}//End input
kInfo = new int[K][3];
for(int i=0; i<K; i++) {
st = new StringTokenizer(br.readLine());
kInfo[i][0] = Integer.parseInt(st.nextToken());
kInfo[i][1] = Integer.parseInt(st.nextToken());
kInfo[i][2] = Integer.parseInt(st.nextToken());
}
int[] nums = new int[K];
boolean[] visited = new boolean[K];
//1. 순열
per(0, visited, nums);
System.out.println(ans);
}
private static void per(int idx, boolean[] visited, int[] nums) {
if(idx>=K) {
//2. 회전
rotate(nums);
return;
}
for(int i=0; i<K; i++) {
if(!visited[i]) {
nums[idx] = i;
visited[i] = true;
per(idx+1, visited, nums);
visited[i] = false;
}
}
}
private static void rotate(int[] nums) {
int[][] tmp = copyMap();
for(int i=0; i<K; i++) {
r = kInfo[nums[i]][0];
c = kInfo[nums[i]][1];
s = kInfo[nums[i]][2];
for(int j=0; j<s; j++) {
lx = r-s+j; //왼쪽 상단 좌표
ly = c-s+j;
rx = r+s-j;
ry = c+s-j; //오른쪽 아래 좌표
//시계방향 회전(우상좌하)
int temp = tmp[lx][ry];
for(int k=ry-1; k>=ly; k--) {
tmp[lx][k+1] = tmp[lx][k];
}
for(int k=lx+1; k<=rx; k++) {
tmp[k-1][ly] = tmp[k][ly];
}
for(int k=ly+1; k<=ry; k++) {
tmp[rx][k-1] = tmp[rx][k];
}
for(int k=rx-1; k>=lx; k--) {
tmp[k+1][ry] = tmp[k][ry];
}
tmp[lx+1][ry] = temp;
}
}
//최소값 구하기
for(int x=1; x<=N; x++) {
int sum = 0;
for(int y=1; y<=M; y++) {
sum += tmp[x][y];
}
ans = Math.min(sum, ans);
}
}
private static int[][] copyMap() {
int[][] tmp = new int[N+1][M+1];
for(int i=1; i<=N; i++) {
for(int j=1; j<=M; j++) {
tmp[i][j] = map[i][j];
}
}
return tmp;
}
}