일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
Tags
- 백준
- java_programming
- MySQL
- 백준 3085번
- 깃헙
- 백준 16918번
- javascript
- 백준 1331번
- 백준 17451번
- 백준 2512번
- ubuntu
- SQL
- 모각코
- Python
- 명품자바
- 머신러닝과 딥러닝
- 다이나믹 프로그래밍
- 알고리즘
- 그리디
- SWEA 15612번
- 다이나믹프로그래밍
- 그래프
- react
- 자바
- 백준 1253번
- HUFS 모각코 캠프
- 백준 1987
- AWS
- 백준 15787번
- 백준 18310번
Archives
- Today
- Total
차곡차곡
[BOJ/Java] 백준 17406번 - 배열 돌리기 4 본문
백준 #117406 배열 돌리기 4
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.StringTokenizer;
public class Main {
static int N, M, K;
static int[][] map;
static int[][] newMap;
static int[][] com;
static int[] comPer;
static int min = Integer.MAX_VALUE;
static int [] dx = {0, 1, 0, -1};
static int [] dy = {1, 0, -1, 0};
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][M]; // 배열
com = new int[K][3]; // 회전 연산
for (int i = 0; i < N; i++) {
st = new StringTokenizer(br.readLine());
for (int j = 0; j < M; j++) {
map[i][j] = Integer.parseInt(st.nextToken());
}
}
for (int i = 0; i < K; i++) {
st = new StringTokenizer(br.readLine());
for (int j = 0; j < 3; j++) {
com[i][j] = Integer.parseInt(st.nextToken());
}
}
comPer = new int[K]; // 회전 연산 순열
// 회전 연산 순열 구하기
makeCom(0, 0);
System.out.println(min);
}
public static void makeCom(int cnt, int flag) {
if (cnt == K) {
// 회전된 배열 저장할 새 배열
newMap = new int[N][M];
for (int i = 0; i < N; i++) {
for (int j = 0; j < M; j++) {
newMap[i][j] = map[i][j];
}
}
for (int i = 0; i < K; i++) {
turn(com[comPer[i]][0]-1, com[comPer[i]][1]-1, com[comPer[i]][2]);
}
findMin();
return;
}
for (int i = 0; i < K; i++) {
if ((flag & 1<<i) != 0) continue;
comPer[cnt] = i;
makeCom(cnt+1, flag | 1<<i);
}
}
// 회전 연산
public static void turn(int r, int c, int s) {
for (int i = 1; i < s+1; i++) {
// 일차원 배열에 값 담기
int len = (int)(Math.pow(1 + i * 2, 2) - Math.pow(1 + (i-1) * 2, 2));
int[] line = new int[len];
int x = r-i;
int y = c-i-1;
int dirNum = 0;
for (int j = 0; j < len; j++) {
int nx = x + dx[dirNum];
int ny = y + dy[dirNum];
if (!(r-i <= nx && nx <= r+i && c-i <= ny && ny <= c+i)) {
dirNum = (dirNum + 1) % 4;
}
x = x + dx[dirNum];
y = y + dy[dirNum];
line[j] = newMap[x][y];
}
// 시계 방향으로 돌려서 넣기
x = r-i;
y = c-i;
dirNum = 0;
for (int j = 0; j < len; j++) {
int nx = x + dx[dirNum];
int ny = y + dy[dirNum];
if (!(r-i <= nx && nx <= r+i && c-i <= ny && ny <= c+i)) {
dirNum = (dirNum + 1) % 4;
}
x = x + dx[dirNum];
y = y + dy[dirNum];
newMap[x][y] = line[j];
}
}
}
// 각 행 최솟값 반환
public static void findMin() {
for (int i = 0; i < N; i++) {
int sum = 0;
for (int j = 0; j < M; j++) {
sum += newMap[i][j];
}
min = Math.min(min, sum);
}
return;
}
} // end of class
- 회전 연산 순서의 순열을 구한다. (모든 경우의 수를 구하는 것)
- 각 순서에 맞춰 회전 연산을 진행한다.
- 돌려야 하는 값들을 일차원 배열에 넣어준 후, 맨왼쪽 위 두 번째 칸부터 시작해서 일차원 배열에 넣은 값들로 채워준다.
- 회전 연산이 끝나면 각 행의 합을 구해 최솟값을 갱신해준다.
- 순열 값들 반복
범위로 준 부분을 다 시계 방향으로 돌리고 행 min 값을 찾아야 되는데, 안쪽 돌리고 찾고, 바깥쪽 돌리고 찾고 이래서 계속 값이 틀리고 있었다. 후
'CS > Algorithm' 카테고리의 다른 글
[BOJ/Java] 백준 1074번 - Z (0) | 2023.08.16 |
---|---|
[BOJ/Python, Java] 백준 2004번 - 조합 0의 개수 (0) | 2023.08.13 |
[BOJ/Java] 백준 11286번 - 절댓값 힙 (0) | 2023.08.10 |
[BOJ/Java] 백준 5014번 - 스타트링크 (0) | 2023.08.10 |
[BOJ/Java] 백준 2210번 - 숫자판 점프 (0) | 2023.08.10 |
Comments