본문 바로가기

Algorithm/문제

[백준 / JAVA] 16927. 배열 돌리기 2 (G5)

https://www.acmicpc.net/problem/16927

 

16927번: 배열 돌리기 2

크기가 N×M인 배열이 있을 때, 배열을 돌려보려고 한다. 배열은 다음과 같이 반시계 방향으로 돌려야 한다. A[1][1] ← A[1][2] ← A[1][3] ← A[1][4] ← A[1][5] ↓ ↑ A[2][1] A[2][2] ← A[2][3] ← A[2][4] A[2][5]

www.acmicpc.net

 

딱히 설명할게 없는 순수 구현 문제...는 배열 돌리기 1만 해당한다. 배열 돌리기 1의 회전수는 1000이지만 2의 회전수는 10억이기에 1을 순수 구현 하고(입력이 1000이면 1000번 움직이도록) 2에 넣으면 시간초과가 필연적이다. 문제를 해결해보자.

 

1. 일단 배열을 한 줄씩 돌리는데 내가 사용한 방법은 n번째 라인을 돌린다면 (n, n)값을 저장한 후 값을 한 칸씩 반시계 방향으로 집어넣는다. 마지막으로 (n+1, n)위치에 저장했던 (n, n)값을 넣는다. 범위는 n ~ (row-n), n ~ (col-n) 으로 잡는다. 

 

2. 회전 횟수를 줄여야 한다. 직관적으로 알겠지만 회전을 구성원 수 만큼 반복하면 초기 상태가 되기 마련이다.(시계를 생각하자) 우리는 배열을 줄마다 돌려야 하니 줄마다 초기 상태가 되는 회전수를 구해서 (주어진 회전 수)%(원점이 되는 회전 수)만큼만 배열을 돌리면 된다. 줄의 구성원 수를 구하는 방법은 ((row-1)+(col-1))*2 이다.

 

아래는 배열 돌리기 1 코드를 넣었을 때

 

import java.io.*;
import java.util.*;

class Main {
	static BufferedReader br;
	static BufferedWriter bw;
	static StringTokenizer st;
	static StringBuilder sb;

	public static void main(String[] args) throws Exception {
		br = new BufferedReader(new InputStreamReader(System.in));
		sb = new StringBuilder();
		st = new StringTokenizer(br.readLine());

		int n = Integer.parseInt(st.nextToken());
		int m = Integer.parseInt(st.nextToken());
		int r = Integer.parseInt(st.nextToken());
		int[][] map = new int[n][m];

		for (int i = 0; i < Math.min(n, m) / 2; i++) {
			int cnt = 2 * ((n - 1 - i * 2) + (m - 1 - i * 2));
		}

		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 cnt = 0; cnt < Math.min(n, m) / 2; cnt++) {
			int rCnt = r % (2 * ((n - 1 - cnt * 2) + (m - 1 - cnt * 2)));

			for (int i = 0; i < rCnt; i++) {
				int save = map[cnt][cnt];
				for (int j = cnt; j < m - 1 - cnt; j++)
					map[cnt][j] = map[cnt][j + 1];
				for (int j = cnt; j < n - 1 - cnt; j++)
					map[j][m - cnt - 1] = map[j + 1][m - cnt - 1];
				for (int j = m - 1 - cnt; j > cnt; j--)
					map[n - cnt - 1][j] = map[n - cnt - 1][j - 1];
				for (int j = n - 1 - cnt; j > cnt; j--)
					map[j][cnt] = map[j - 1][cnt];
				map[cnt + 1][cnt] = save;
			}
		}
		for (int[] mp : map) {
			for (int v : mp)
				sb.append(v + " ");
			sb.append("\n");
		}
		System.out.println(sb);
	}
}