Algorithm/Algorithm Problem
백준 17406 배열 돌리기4(구현)
땅지원
2022. 8. 12. 08:55
https://www.acmicpc.net/problem/17406
17406번: 배열 돌리기 4
크기가 N×M 크기인 배열 A가 있을때, 배열 A의 값은 각 행에 있는 모든 수의 합 중 최솟값을 의미한다. 배열 A가 아래와 같은 경우 1행의 합은 6, 2행의 합은 4, 3행의 합은 15이다. 따라서, 배열 A의
www.acmicpc.net
1. 배열에 대해서 permutation을 돌리는 기법이 자바에서 구현하기 많이 힘들었다.
==> row에 대한 인덱스들만 따로 모은 1차원 배열을 permutation 돌리는 기법으로 하는게 정석인 것 같음
2. rotation 시키는 방법
2-1. (in java) list에 넣고 Collections.rotate()
2-1-1 (in python) queue.rotate()
2-2 배열에 넣고 시작값만 temp에 넣어서 보관한 다음에 한칸씩 밀어버리고 제일 마지막 값만 temp에 있는걸 넣어준다.
<Java>
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Queue;
import java.util.StringTokenizer;
public class Main {
static int[][] board, rotate_infor, temp_board;
static int n, m, k;
static int res = 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());
board = new int[n][m];
for (int i = 0; i < n; i++) {
st = new StringTokenizer(br.readLine());
for (int j = 0; j < m; j++) {
board[i][j] = Integer.parseInt(st.nextToken());
}
}
rotate_infor = new int[k][3];
for (int i = 0; i < k; i++) {
st = new StringTokenizer(br.readLine());
for (int j = 0; j < 3; j++) {
rotate_infor[i][j] = Integer.parseInt(st.nextToken());
}
}
// 구현
// permu 돌리기위한 준비
int[] data = new int[k];
int[] number = new int[k];
boolean[] visited = new boolean[k];
for (int i = 0; i < k; i++) {
data[i] = i;
}
permutation(0, data, number, visited);
System.out.println(res);
}
public static int check_min_row() {
int total = Integer.MAX_VALUE;
for (int i = 0; i < n; i++) {
int row_value = 0;
for (int j = 0; j < m; j++) {
row_value += temp_board[i][j];
}
total = Math.min(total, row_value);
}
return total;
}
public static void rotation(int x, int y, int length) {
List<Integer> list_queue = new ArrayList<>();
for (int i = y; i < y + length; i++) {
list_queue.add(temp_board[x][i]);
}
for (int i = x + 1; i < x + length; i++) {
list_queue.add(temp_board[i][y + length - 1]);
}
for (int i = y + length - 2; i > y - 1; i--) {
list_queue.add(temp_board[x + length - 1][i]);
}
for (int i = x + length - 2; i > x; i--) {
list_queue.add(temp_board[i][y]);
}
Collections.rotate(list_queue, 1);
Queue<Integer> queue = new ArrayDeque<>(list_queue);
for (int i = y; i < y + length; i++) {
temp_board[x][i] = queue.poll();
}
for (int i = x + 1; i < x + length; i++) {
temp_board[i][y + length - 1] = queue.poll();
}
for (int i = y + length - 2; i > y - 1; i--) {
temp_board[x + length - 1][i] = queue.poll();
}
for (int i = x + length - 2; i > x; i--) {
temp_board[i][y] = queue.poll();
}
}
public static void permutation(int depth, int[] data, int[] number, boolean[] visited) {
if (depth == k) {
// 순열이 만들어질 때 마다 rotate돌려서 테스트 해야되니까 기저조건 안에 해보자
temp_board = new int[n][m];
for (int idx_i = 0; idx_i < n; idx_i++) {
for (int idx_j = 0; idx_j < m; idx_j++) {
temp_board[idx_i][idx_j] = board[idx_i][idx_j];
}
}
for (int tc : number) {
int r = rotate_infor[tc][0];
int c = rotate_infor[tc][1];
int s = rotate_infor[tc][2];
int x = r - s - 1;
int y = c - s - 1;
int len = (s * 2) + 1;
while (true) {
if (len <= 0)
break;
rotation(x, y, len);
x++;
y++;
len -= 2;
}
}
res = Math.min(check_min_row(), res);
return;
}
for (int i = 0; i < k; i++) {
if (!visited[i]) {
visited[i] = true;
number[depth] = data[i];
permutation(depth + 1, data, number, visited);
visited[i] = false;
}
}
}
}
<Python>
from itertools import permutations
from collections import deque
import copy
def check_min_value(arr):
temp = []
for i in arr:
temp.append(sum(i))
return min(temp)
def rotate(x,y,length):
queue = deque()
for i in range(y,y+length):
queue.append(temp_data[x][i])
for i in range(x+1,x+length):
queue.append(temp_data[i][y+length-1])
for i in range(y+length-2,y-1,-1):
queue.append(temp_data[x+length-1][i])
for i in range(x+length-2,x,-1):
queue.append(temp_data[i][y])
queue.rotate(1)
for i in range(y,y+length):
temp_data[x][i] = queue.popleft()
for i in range(x+1,x+length):
temp_data[i][y+length-1] = queue.popleft()
for i in range(y+length-2,y-1,-1):
temp_data[x+length-1][i] = queue.popleft()
for i in range(x+length-2,x,-1):
temp_data[i][y] = queue.popleft()
n,m,k = list(map(int,input().split()))
data = [list(map(int,input().split())) for _ in range(n)]
per = []
for _ in range(k):
per.append(list(map(int,input().split())))
per = permutations(per)
res = 9876543210
for p in per:
temp_data = copy.deepcopy(data)
for rotation in p:
r,c,s = rotation
x = r-s-1
y = c-s-1
length = (s * 2) +1
while True:
if length <= 0:
break
rotate(x,y,length)
x += 1
y += 1
length -= 2
res = min(check_min_value(temp_data),res)
print(res)