문제 링크
https://www.acmicpc.net/problem/16926
풀이
- 테두리 단위로 배열을 돌리기 위해 큐를 사용했다. 정확히는 원형 큐의 방식을 차용해서 배열 값을 순환할 수 있도록 했다.
- 문제는 테두리의 개수를 정하는 과정에 있었는데, 문제의 조건 중 하나가 배열의 행
n
과 열m
중 작은 값은 무조건 짝수라는 점을 간과했다. (min(N, M) mod 2 = 0
) 이를 통해 배열의 테두리 개수는n
과m
중 더 작은 값을2
로 나눈 것과 같다. 하지만 이를 알아채지 못하고 테두리의 개수를n/2
로 고정해버려서 계속 오답 처리가 되었다. - 각 테두리의 좌측 상단부터 시계 방향으로 값을 큐에 담고,
r
만큼 맨 앞의 값을 뽑고 다시 맨 뒤에 넣는 것을 반복했다. 그리고 다시 좌측 상단부터 시계 방향으로 큐의 값을 하나씩 뽑아서 배열에 저장했다. - 큐를 사용하는 대신 각 테두리의 좌측 상단을 임시로 저장하고 시계 방향으로 모든 요소를 한 칸씩 당긴 다음, 저장한 값을 처음 위치의 바로 아래 행에 저장하는 방법도 있다. 시간 상 따로 구현하지는 않았다.
소스 코드
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.LinkedList;
import java.util.Queue;
import java.util.StringTokenizer;
/**
* 백준 16926번: 배열 돌리기 1
*/
public class Main {
private static int[][] arr;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
int n = Integer.parseInt(st.nextToken());
int m = Integer.parseInt(st.nextToken());
int r = Integer.parseInt(st.nextToken());
// 델타 배열 초기화 (우측부터 시계 방향)
int[] dr = {0, 1, 0, -1};
int[] dc = {1, 0, -1, 0};
// 배열 초기화
arr = new int[n][m];
for (int i = 0; i < n; i++) {
st = new StringTokenizer(br.readLine());
for (int j = 0; j < m; j++) {
arr[i][j] = Integer.parseInt(st.nextToken());
}
}
// 배열의 현재 테두리의 모든 원소를 담기 위한 큐 생성
Queue<Integer> queue = new LinkedList<>();
// 테두리의 개수는 n과 m 중 더 작은 값을 2로 나눈 것과 같음
for (int i = 0; i < Math.min(n, m) / 2; i++) {
// 좌측 상단부터 시계 방향으로 큐에 삽입
int row = i, col = i, dir = 0;
for (int j = 0; j < (n+m-4*i-2)*2; j++) {
queue.offer(arr[row][col]);
row += dr[dir];
col += dc[dir];
if (dir == 0 && col + 1 >= m - i) dir = ++dir % 4;
else if (dir == 1 && row + 1 >= n - i) dir = ++dir % 4;
else if (dir == 2 && col - 1 < i) dir = ++dir % 4;
else if (dir == 3 && row - 1 < i) dir = ++dir % 4;
}
// 맨 앞 원소를 r번 뽑아서 다시 큐에 삽입
for (int j = 0; j < r; j++) queue.offer(queue.poll());
// 다시 좌측 상단부터 시계 방향으로 배열에 입력
row = i;
col = i;
dir = 0;
for (int j = 0; j < (n+m-4*i-2)*2; j++) {
arr[row][col] = queue.poll();
row += dr[dir];
col += dc[dir];
if (dir == 0 && col + 1 >= m - i) dir = ++dir % 4;
else if (dir == 1 && row + 1 >= n - i) dir = ++dir % 4;
else if (dir == 2 && col - 1 < i) dir = ++dir % 4;
else if (dir == 3 && row - 1 < i) dir = ++dir % 4;
}
queue.clear();
}
// 배열 출력
printArray();
br.close();
}
public static void printArray() {
StringBuilder sb = new StringBuilder();
StringBuilder row;
for (int i = 0; i < arr.length; i++) {
row = new StringBuilder();
for (int j = 0; j < arr[i].length; j++) {
row.append(arr[i][j] + " ");
}
row.setLength(row.length() - 1);
sb.append(row + "\n");
}
System.out.print(sb.toString());
}
}