티스토리 뷰

개발/알고리즘

[구름] 전광판 광고

최컬리 2019. 9. 24. 15:39

 배열로 이루어진 행렬 자체에서 값들을 이동시켰다면 테두리의 크기에 따라 달라지는 2차원 인덱스를 처리하기 훨씬 까다로웠을 것이다. 테두리 값을 리스트에 가져와서 Collections 클래스의 rotate() 메서드를 사용해 따로 버퍼를 두지 않고도 쉽게 회전 이동을 처리했고, 다시 배열에 되돌려 놓았다. 한 번 실행될 때마다 회전 방향은 반대로 바꿔주었다.

 문제를 풀기 전에 신경 썼던 것은 주어진 행렬의 크기에 따른 테두리 길이의 변화와 회전수의 값이 클 때 이를 주기로 나누어서 해결하는 것, 결과를 출력할 때 각 행이 공백 문자열 없이 개행(\n)으로 끝나는 것이었다.

import java.util.*;

public class Test {

	public static void main(String[] args) throws Exception {
		// 3 -777
		// 강미나 김도연 김세정
		// 김소혜 김청하 유연정
		// 임나영 전소미 정채연

		// 입력 받기
		Scanner stdIn = new Scanner(System.in);
		int size = stdIn.nextInt();	// 행렬의 크기 (1 < N <= 100)
		int rotate = stdIn.nextInt();	// 회전수 W (-1,000,000,000 <= W <= 1,000,000,000)
		boolean clockwise = (rotate >= 0) ? true : false;

		String[][] names = new String[size][size];
		for (int i = 0; i < size; i++) {
			for (int j = 0; j < size; j++) {
				names[i][j] = stdIn.next();
			}
		}

		// 회전 시키기
		LinkedList<String> list = new LinkedList<>();
		
		for (int i = 0; i < size / 2; i++) { 	// 크기에 따른 회전 테두리 수
			int base = size - 1 - (2 * i); 	// 연산을 위한 각 테두리의 기본 수
			int rotateT = base * 4; 	// 원점으로 돌아오는 회전 수(주기)

			// 배열에서 추출하기 (시계방향 순서로)
			for (int j2 = 0; j2 < base; j2++) {	
				list.add(names[i][i + j2]);
			}
			for (int j2 = 0; j2 < base; j2++) {	
				list.add(names[i+j2][i+base]);
			}
			for (int j2 = 0; j2 < base; j2++) { 
				list.add(names[i+base][i+base-j2]);
			}
			for (int j2 = 0; j2 < base; j2++) {	
				list.add(names[i+base-j2][i]);
			}

			// 회전
			if(clockwise == true)
				Collections.rotate(list, Math.abs(rotate%rotateT));
			else
				Collections.rotate(list, -Math.abs(rotate%rotateT));
			
			// 배열에 되돌려놓기
			int index = 0;
			for (int j2 = 0; j2 < base; j2++) {
				names[i][i + j2] = list.get(index++);
			}
			for (int j2 = 0; j2 < base; j2++) {
				names[i+j2][i+base] = list.get(index++);
			}
			for (int j2 = 0; j2 < base; j2++) {
				names[i+base][i+base-j2] = list.get(index++);
			}
			for (int j2 = 0; j2 < base; j2++) {
				names[i+base-j2][i] = list.get(index++);
			}
			
			list.clear();
			clockwise = (clockwise == true) ? false : true; 
		}
		// 결과 출력하기
		print(names);
	}

	// 결과 출력
	static void print(String[][] names) {
		for (int i = 0; i < names.length; i++) {
			StringBuffer sb = new StringBuffer();
			for (String name : names[i]) {
				sb.append(name).append(" ");
			}
			sb.deleteCharAt(sb.length() - 1);
			System.out.println(sb);
		}
	}
}

 

 문제를 해결하면서 처음에 놓쳤던 것은 맞닿은 테두리는 반대 방향으로 회전한다는 것, 두 번째는 이름의 길이가 다른 경우였다. 

 다음에 다시 풀게 된다면 for문으로 각 테두리를 처리한 것을 자신의 단계에서 하나의 테두리를 처리하고 내부의 행렬을 넘겨주면서 재귀적으로 처리하면 좋을 것 같다고 생각을 했는데 안쪽의 행렬을 넘겨주고 또 그 결과를 합성하기가 어려울 것 같다.

댓글