[백준 16296] 배열 돌리기 1 (자바)
알고리즘/백준

[백준 16296] 배열 돌리기 1 (자바)

반응형

백준 16296번 배열 돌리기 1 (자바)

 

 

 

출처

www.acmicpc.net/problem/16926

 

16926번: 배열 돌리기 1

크기가 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

 

 

 

문제

크기가 N×M인 배열이 있을 때, 배열을 돌려보려고 한다. 배열은 다음과 같이 반시계 방향으로 돌려야 한다.

예를 들어, 아래와 같은 배열을 2번 회전시키면 다음과 같이 변하게 된다.

배열과 정수 R이 주어졌을 때, 배열을 R번 회전시킨 결과를 구해보자.

 

 

 

입력

첫째 줄에 배열의 크기 N, M과 수행해야 하는 회전의 수 R이 주어진다.

둘째 줄부터 N개의 줄에 배열 A의 원소 Aij가 주어진다.

 

 

 

출력

입력으로 주어진 배열을 R번 회전시킨 결과를 출력한다.

 

 

 

제한

  • 2 ≤ N, M ≤ 300
  • 1 ≤ R ≤ 1,000
  • min(N, M) mod 2 = 0
  • 1 ≤ Aij ≤ 108

 

 

 

입출력 예

입출력 예 1
입출력 예 2

 

 

 

접근 방법

주어지는 배열에 따라 돌려야 하는 개수가 달라진다. 이는 (행, 열 중 낮은 값/2) 하면 구할 수 있다.

 

1. 주어진 r만큼 배열을 돌린다.

 

2. 그 후, 총 돌려야 하는 개수(num)만큼 돌려준다.

 

3. 나는 왼쪽 맨 위의 행렬 값이 0,0 1,1 2,2... 이렇게 동일하게 진행되기 때문에 해당 값을 빼놓고 나중에 연산 후에 다시 넣어주었다.

 

4. 미리 지정한 우,하,좌,상 순서대로 while문을 진행한다.

(이렇게 진행하는 이유는 반시계로 옮기기 위해 해당 행이나 열을 한 칸씩 옮기기 위함이다.)

 

5. 행렬 범위 넘어가는 경우 방향을 변경해야 하므로 index+1 해준다.

 

6. 4방향 다 연산하면 처음에 빼놓았던 값을 한 행 밑에 넣어준다.(1,1 -> 2,1로 이동했기 때문)

 

 

 

내 코드

package guhyun;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class ArrayCirculation {
	/**
	 * 백준 16926 배열 돌리기 1 (https://www.acmicpc.net/problem/16926)
	 */

	private static int n, m, r;
	private static int[][] map;
	
	private static int[] dx = {0, 1, 0, -1};//우상좌하
	private static int[] dy = {1, 0, -1, 0};
	
	public static void main(String[] args) throws IOException {
		
		BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
		
		StringTokenizer st = new StringTokenizer(reader.readLine());
		
		n = Integer.parseInt(st.nextToken());
		m = Integer.parseInt(st.nextToken());
		r = Integer.parseInt(st.nextToken());
		
		map = new int[n+1][m+1];
		
		for (int i=1; i<=n; i++) {
			st = new StringTokenizer(reader.readLine());
			for (int j=1; j<=m; j++) {
				map[i][j] = Integer.parseInt(st.nextToken());
			}
		}
		
		//총 돌려야 하는 네모 개수
		int num = Math.min(n, m)/2;
		
		for (int i=0; i<r; i++) {
			circulate(num);
		}
		
		for (int i=1; i<=n; i++) {
			for (int j=1; j<=m; j++) {
				System.out.print(map[i][j] + " ");
			}
			System.out.println();
		}
		
	}//main

	private static void circulate(int num) {
		
		for (int i=1; i<=num; i++) {
			//네모들의 왼쪽 맨위의 좌표는 1,1 || 2,2 || 3,3 || ...
			int x = i;
			int y = i;
			int temp = map[x][y]; //첫번째 값을 담아놓고 연산 후에 넣어준다.
			
			int index = 0;
			
			while (index < 4) {
				
				int nx = x + dx[index];
				int ny = y + dy[index];
				
				if (nx < i || ny < i || nx > n-i+1 || ny > m-i+1) {
					index++;
				} else {
					map[x][y] = map[nx][ny];
					
					x = nx;
					y = ny;
				}
				
			}//while
			map[i+1][i] = temp;
		}//for
		
	}//circulate()

}




 

 

 

고려할 점

1. 전체 돌릴 개수를 구할 규칙을 찾을 것

2. 돌리는 방법을 생각할 것

 

 

반응형