[백준 16935번] 배열돌리기3

2025. 5. 17. 15:31·알고리즘
728x90
반응형

 

문제번호: https://www.acmicpc.net/problem/16935

 

 

 

문제의 유형

  • 구현

 

해당 문제풀이를 진행할 때, 최대한 단순하게 진행하려고 노력하였다. 이중 포문을 활용할 때, 변수를 4개 사용하는 대신, 조금 더 직관적으로 표현할 수 있어, 시간 복잡도는 늘어날지라도 헷갈리지 않기 위해 노력하였다.

 

중간에 배열을 오른쪽으로 90도 회전하거나, 왼쪽으로 90도 회전할 경우, 배열의 가로 행과 세로 행의 길이가 서로 달라지기 때문에 해당 부분은 유의해서 문제풀이를 진행하여야 한다.

 

package _250517;

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

/**
 *packageName    : _250517
 * fileName       : BOJ_G5_16935_배열돌리기3
 * author         : moongi
 * date           : 5/17/25
 * description    :
 */
public class BOJ_G5_16935_배열돌리기3 {
	static int N, M, K;
	static int[][] board;

	public static void main(String[] args) throws Exception {
		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());

		board = new int[N][M];

		for (int i = 0; i < N; i++) {
			st = new StringTokenizer(br.readLine());
			for (int j = 0; j < M; j++) {
				board[i][j] = Integer.parseInt(st.nextToken());
			}
		}

		st = new StringTokenizer(br.readLine());

		int[][] res = copyArr(board);
		int cnt = 0;
		for (int i = 0; i < K; i++) {
			int oper = Integer.parseInt(st.nextToken());

			if (oper == 1) res =op1(res);
			else if (oper == 2) res = op2(res);
			else if (oper == 3) {
				res = op3(res);
				cnt++;
			}
			else if (oper == 4) {
				res = op4(res);
				cnt++;
			}
			else if (oper == 5) res = op5(res);
			else if (oper == 6) res = op6(res);
		}

		StringBuilder sb = new StringBuilder();
		if (cnt % 2 == 0) {
			for (int i = 0; i < N; i++) {
				for (int j = 0; j < M; j++) {
					sb.append(res[i][j] + " ");
				}
				sb.append('\n');
			}
		} else {
			for (int i = 0; i < M; i++) {
				for (int j = 0; j < N; j++) {
					sb.append(res[i][j] + " ");
				}
				sb.append('\n');
			}
		}

		System.out.println(sb);
	}

	static int[][] copyArr(int[][] arr) {
		int[][] copied = new int[N][M];

		for (int i = 0; i < N; i++) {
			copied[i] = arr[i].clone();
		}

		return copied;
	}

	static int[][] op1(int[][] arr) {
		int[][] copied = new int[arr.length][arr[0].length];

		int idx = arr.length - 1;
		for (int i = 0; i < arr.length; i++) {
			copied[i] = arr[idx--].clone();
		}

		return copied;
	}

	static int[][] op2(int[][] arr) {
		int[][] copied = new int[arr.length][arr[0].length];

		// 순서 바꿨을 떄, N, M 바뀌는 거 유의하고.
		for (int i = 0, k = arr[0].length - 1; i < arr[0].length && k >= 0; i++, k--) {
			for (int j = 0; j < arr.length; j++) {
				copied[j][k] = arr[j][i];
			}
		}

		return copied;
	}


	// 배열의 크기가 변경됨.
	static int[][] op3(int[][] arr) {
		int[][] copied = new int[arr[0].length][arr.length];

		for (int i = 0, k = copied[0].length - 1; i < arr.length && k >= 0; i++, k--) {
			for (int j = 0, l = 0; j < arr[0].length && l < copied.length; j++, l++) {
				copied[l][k] = arr[i][j];
			}
		}

		return copied;

	}

	static int[][] op4(int[][] arr) {

		int[][] copied = new int[arr[0].length][arr.length];

		for (int i = 0, k = 0; i < arr.length && k < copied[0].length; i++, k++) {
			for (int j = arr[0].length-1, l = 0; j >=0 && l < copied.length; j--, l++) {
				copied[l][k] = arr[i][j];
			}
		}

		return copied;

	}

	static int[][] op5(int[][] arr) {
		int[][] copied = new int[arr.length][arr[0].length];
		int N = arr.length;
		int M = arr[0].length;

		// 4 -> 1
		for (int i = N / 2, k = 0; i < N && k < N / 2; i++, k++) {
			for (int j = 0, l = 0; j < M / 2 && l < M / 2; j++, l++) {
				copied[k][l] = arr[i][j];
			}
		}
		// 3 -> 4
		for (int i = N / 2, k = N/2; i < N && k < N; i++, k++) {
			for (int j = M / 2, l = 0; j < M && l < M / 2; j++, l++) {
				copied[k][l] = arr[i][j];
			}
		}

		// 2 -> 3
		for (int i = 0, k = N/2; i < N / 2 && k < N; i++, k++) {
			for (int j = M / 2, l = M / 2; j < M && l < M; j++, l++) {
				copied[k][l] = arr[i][j];
			}
		}

		// 1 -> 2
		for (int i = 0, k = 0; i < N / 2 && k < N / 2; i++, k++) {
			for (int j = 0, l = M / 2; j < M / 2 && l < M; j++, l++) {
				copied[k][l] = arr[i][j];
			}
		}

		return copied;
	}

	static int[][] op6(int[][] arr) {
		int[][] copied = new int[arr.length][arr[0].length];
		int N = arr.length;
		int M = arr[0].length;

		// 2, 3
		// 1 -> 4
		for (int i = 0, k = N/2; i < N / 2 && k < N; i++, k++) {
			for (int j = 0, l = 0; j < M / 2 && l < M / 2; j++, l++) {
				copied[k][l] = arr[i][j];
			}
		}
		// 4 -> 3
		for (int i = N / 2, k = N / 2; i < N && k < N; i++, k++) {
			for (int j = 0, l = M / 2; j < M / 2 && l < M; j++, l++) {
				copied[k][l] = arr[i][j];
			}
		}
		// 3 -> 2
		for (int i = N / 2, k = 0; i < N && k < N / 2; i++, k++) {
			for (int j = M/2, l = M / 2; j < M && l < M; j++, l++) {
				copied[k][l] = arr[i][j];
			}
		}

		// 2 -> 1
		for (int i = 0, k = 0; i < N /2 && k < N / 2; i++, k++) {
			for (int j = M / 2, l = 0; j < M && l < M / 2; j++, l++) {
				copied[k][l] = arr[i][j];
			}
		}

		return copied;
	}

}

 

 

추가

다른 사람은 다음과 같이 풀었다.

해당 풀이는 두개의 변수를 활용한 이중 포문을 활용하면서 배열을 변형하였다.

깔끔한 풀이지만, 실제 코딩테스트를 진행할 때, 이렇게까지 고려하진 못할 것 같다.

 

	public static void op1(){
        tmpMap = new int[n][m];
        for(int i=0; i<n; i++){
            for(int j=0; j<m; j++){
                tmpMap[n-i-1][j] = map[i][j];  //행만 서로 반대
            }
        }
        map = tmpMap;
    }
    
	public static void op2(){
        //2번 연산 : 좌우 반전
        tmpMap = new int[n][m];
        for(int i=0; i<n; i++){
            for(int j=0; j<m; j++){
               tmpMap[i][m-j-1] = map[i][j]; //열만 반대
            }
        }
        map = tmpMap;
    }
    
    public static void op3(){
        //3번 연산 : 오른쪽 90도 회전
        tmpMap = new int[m][n];
 
        for(int i=0; i<n; i++){
 
            for(int j=0; j<m; j++){
                //System.out.println("i, j : " + i + ", " + j);
                //System.out.println(j + ", " + (n-i-1));
                tmpMap[j][n-i-1] =  map[i][j];
            }
        }
        //배열 바꾸기 => 결과 배열 크기 다르므로
        int tmp = n;
        n = m;
        m= tmp;
 
        map = tmpMap;
 
    }
    
    public static void op4(){
        //4번 연산 : 왼쪽 90도 회전
        tmpMap = new int[m][n];
        for(int i=0; i<n; i++){
            for(int j=0; j<m; j++){
                tmpMap[m-j-1][i] =  map[i][j];
            }
        }
        //배열 바꾸기
        int tmp = n;
        n = m;
        m= tmp;
 
        map = tmpMap;
 
 
    }
    
    public static void op5(){
        //5번 연산 : 4그룹 1->2, 2->3, 3->4, 4->1
        tmpMap = new int[n][m];
        for(int i=0; i<n/2; i++){
            for(int j=0; j<m/2; j++){
                tmpMap[i][m/2+j] = map[i][j];
 
            }
        }
 
        // 0,4 -> 3,4
        for(int i=0; i<n/2; i++){
            for(int j=m/2; j<m; j++){
                tmpMap[n/2+i][j] = map[i][j];
            }
        }
        // 3,4 -> 3,0
        for(int i=n/2; i<n; i++){
            for(int j=m/2; j<m; j++){
                tmpMap[i][j-m/2] = map[i][j];
            }
        }
        // 3,0 -> 0,0
        for(int i=n/2; i<n; i++){
            for(int j=0; j<m/2; j++){
                tmpMap[i-n/2][j] = map[i][j];
            }
        }
        map = tmpMap;
 
    }
    public static void op6(){
        // 4그룹 1->2, 2->3, 3->4, 4->1
        //6번 연산 : 4그룹 1->4, 4->3, 3->2, 2->1
        tmpMap = new int[n][m];
        // 0,0 -> 3,0
        for(int i=0; i<n/2; i++){
            for(int j=0; j<m/2; j++){
                tmpMap[n/2+i][j] = map[i][j];
 
            }
        }
        
 
        // 3,0 -> 3,4
        for(int i=n/2; i<n; i++){
            for(int j=0; j<m/2; j++){
                tmpMap[i][j+m/2] = map[i][j];
            }
        }
        // 3,4 -> 0,4
        for(int i=n/2; i<n; i++){
            for(int j=m/2; j<m; j++){
                tmpMap[i-n/2][j] = map[i][j];
            }
        }
       
 
        // 0,4 -> 0,0
        for(int i=0; i<n/2; i++){
            for(int j=m/2; j<m; j++){
                tmpMap[i][j-m/2] = map[i][j];
            }
        }
        
        map = tmpMap;
 
    }
}

 

참고 블로그

https://eonhwa-theme.tistory.com/29

 

[16935][java][백준]배열 돌리기 3

알고리즘 분류 구현 문제 풀이 이번 문제는 실버2임에도 불구하고 쉬운편! 하지만 계산과정이 많아서 귀찮고 머리가 복잡하다.. 1번 연산 : 배열 상하 반전 2번 연산 : 좌우 반전 3번 연산 : 오른쪽

eonhwa-theme.tistory.com

 

728x90
반응형
저작자표시 비영리 변경금지 (새창열림)

'알고리즘' 카테고리의 다른 글

[PCCP 기출 4번] 수식 복원하기  (1) 2025.05.20
[백준 12100번] 2048 (Easy)  (0) 2025.05.17
[백준 10159번] 저울  (0) 2025.05.14
[백준 5557번] 1학년  (0) 2025.05.13
[백준 2655번] 가장높은탑쌓기  (0) 2025.05.13
'알고리즘' 카테고리의 다른 글
  • [PCCP 기출 4번] 수식 복원하기
  • [백준 12100번] 2048 (Easy)
  • [백준 10159번] 저울
  • [백준 5557번] 1학년
moongi
moongi
프로그래밍 관련 공부를 정리하는 블로그
  • moongi
    By_Me
    moongi
  • 전체
    오늘
    어제
    • 공부 (57) N
      • 알고리즘 (25) N
        • 기업별 유사 문제 (2)
        • Sudo Code (4)
        • 예외처리 (1)
        • SQL (5)
      • spring boot (6)
        • jpa (0)
        • querydsl (0)
        • MVC pattern (0)
        • setting (2)
      • 취준 (6)
      • CS (8)
        • 디자인패턴 (1)
        • 데이터베이스 (4)
        • 네트워크 (3)
        • 운영체제 (0)
  • 인기 글

  • 최근 댓글

  • hELLO· Designed By정상우.v4.10.3
moongi
[백준 16935번] 배열돌리기3
상단으로

티스토리툴바