본문 바로가기
백준

[백준] code.plus(시뮬레이션과 구현,JAVA)16927번, 배열 돌리기 2

by 열정적인 이찬형 2022. 5. 8.

문제 링크

 

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

 


주의사항

  • JAVA를 사용하여 프로그램을 사용하였습니다.
  • 백준에서 코드를 작성하였을 때 아래 형태에서 Main에서 결과가 출력되어야 합니다.
public class Main{ 	
	public static void main(String[] args){
    }
}

문제 설명

 


접근 방법

 

이 문제를 풀기 전 아래 링크의 문제를 먼저 풀어오는 것을 추천드립니다.

이유는 이 문제에 대하여 설명할 때 회전하는 방법은 아래의 문제에서 다루었기 때문에 아래 링크의 문제와 이번 문제의 차이점을 다루며 설명할 것입니다.

 

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]

아래 링크는 배열돌리기 1번에 대한 문제를 제가 해설한 내용입니다.

 

[백준] code.plus(시뮬레이션과 구현,JAVA)16926번, 배열 돌리기 1

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

tussle.tistory.com

이 문제에 핵심은

1. 배열을 R번 돌린 배열 값들을 출력해야 합니다.

2. 배열을 회전할 때에는 반시계로 돌리며 각 범위별로 회전합니다.

 

사용되는 배열

arr[][] : 입력 배열을 저장하고 변경되어 결과로 출력되는 배열

 

문제 배열돌리기 1과 차이점은 회전하는 R의 값의 최대값이 매우 커졌다는 것입니다.

기존의 코드로 문제를 해결하려고 하면 시간초과가 무조건 발생할 수밖에 없습니다.

 

각 범위마다 회전할 때 처음 회전의 값으로 되돌아오는 것을 이용해야 합니다.

 

 

배열의 범위을 살펴보면

1 1 1 1
1 2 2 1
1 2 2 1
1 1 1 1

빨간색 범위에서는 12번을 회전하면 처음의 상태로 되돌아옵니다.

파란색 범위에서는 4번을 회전하면 처음의 상태로 되돌아옵니다.

 

처음으로 돌아오는 횟수를 이용하여 만약 빨간색이 50번을 회전한다면 2번 회전하는 경우와 같습니다.

50 % 12 = 2로 표현할 수 있기 때문입니다.

 

동일하게 파란색도 50번 회전하면

50 % 4 = 2로 2번 회전하는 경우와 같습니다.

 

이제 처음의 상태로 되돌아오는 횟수를 구하는 방법을 알아보면

 

범위의 크기가(N×M)인 경우 점화식은

(2*n) + (2*m) - 4 = 처음으로 돌아오는 회전 횟수

 

빨간색 범위일 때(4×4)

2*4 + 2*4 - 4 = 12

 

파란색 범위일 때(2×2)

2*2 + 2*2 - 4 = 4

 

각 범위별 (R%처음으로 돌아오는 회전 횟수)번을 회전을 진행한 뒤

배열의 값들을 저장한 뒤 최종적으로 만들어진 배열을 결과로 출력합니다.

 

문제를 해결한 알고리즘의 과정입니다.

1. 입력값 N×M 배열의 값과 R을 받습니다.

2. 배열의 각 범위마다 (R%원상태로 돌아오는 회전 횟수)번의 회전을 진행합니다.

3. 모든 회전이 끝난 뒤 배열에 값들을 결과로 출력합니다.

 

  • BufferedReader를 사용하여 입력 값을 받았습니다.
  • StringTokenizer를 이용하여 N×M배열과 N,M,R개의 연산을 나누었습니다.
  • 각 범위별 (R%원상태로 돌아오는 회전횟수)번 배열을 회전하는 rotation함수를 만들었습니다.
  • R rotation 함수를 실행시켜 회전합니다.
  • BufferedWriter에 회전으로 변경된 최종 배열을 저장하였습니다
  • BufferedWriter에 저장된 값을 결과로 출력하였습니다
  • rotation함수는 구역을 나누어 값들을 회전하는 함수입니다.

결과 코드

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

public class Main {
	static int[][] arr;	//회전할 배열
	static int N,M,R;
    public static void main(String[] args) throws IOException {
    	BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        //입력값 처리하는 BufferedReader
    	BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
        //결과값 출력하는 BufferedWriter
    	StringTokenizer st = new StringTokenizer(br.readLine()," ");
    	N = Integer.parseInt(st.nextToken());
    	M = Integer.parseInt(st.nextToken());
    	R = Integer.parseInt(st.nextToken());
    	int space = Math.min(N, M)/2;		//공간 개수
    	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());
    		}
    	}
    	//기준
    	int n = N;
    	int m = M;
        //크기
    	int width = N;
    	int weight = M;
    	for(int i=0;i<space;i++) {
    		rotation(i,n,m,width,weight);
            //기준 감소
    		n-=1;
    		m-=1;
            //크기 감소
    		width-=2;
    		weight-=2;
    	}
        //회전한 후 배열값들 BufferedWriter 저장
    	for(int i=0;i<N;i++) {
    		for(int j=0;j<M;j++) {
    			bw.write(arr[i][j] + " ");
    		}
    		bw.newLine();
    	}
    	bw.flush();		//결과 출력
    	bw.close();
    	br.close();
    }
    //각 범위별 (R%원상태로 돌아오는 회전 횟수)번 회전하는 함수
    static void rotation(int space, int n, int m, int width, int weight) {
    	int repeat = R % (width*2 + weight*2 - 4);		//원상태로 돌아오는 회전 횟수
    	for(int i=0;i<repeat;i++) {
        	int temp = arr[space][space];
    		for(int j=space;j<m-1;j++)		//←
    			arr[space][j] = arr[space][j+1];  		
    		for(int j=space;j<n-1;j++)		//↑
    			arr[j][m-1] = arr[j+1][m-1];
    		for(int j=m-1;j>space;j--)		//→
    			arr[n-1][j] = arr[n-1][j-1];
    		for(int j=n-1;j>space;j--)		//↑
    			arr[j][space] = arr[j-1][space];
    		arr[space+1][space] = temp;
    	}
    	return;
    }
}

댓글