[PS] 백준 1022 - 소용돌이 예쁘게 출력하기

2020. 5. 19. 02:44알고리즘/PS

* 문제 링크

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

 

1022번: 소용돌이 예쁘게 출력하기

첫째 줄에 r1, c1, r2, c2가 주어진다. 모두 절댓값이 5000보다 작거나 같은 정수이고, r2-r1은 0보다 크거나 같고, 49보다 작거나 같으며, c2-c1은 0보다 크거나 같고, 4보다 작거나 같다.

www.acmicpc.net

문제 이해

1. 기존에 정사각형으로 소용돌이 형태로 출력하는 문제랑 유사하다.

2. format과 같은 함수를 이용해 자리수를 맞춰서 출력해야 한다.

3. 그림과는 다르게 네모칸 숫자만 출력하면 되기 때문에 어렵지 않은 문제이다.

 

문제 풀이

row와 column이 절대값이 5000보다 작다고 하니 최대로 나올수 있는 칸의 수는 10000*10000 1억 이므로 주어지는

시간 2초안에 계산이 가능하다.

1억개 이므로 int배열로 충분하지만 전부 구하기 위해서 1억개의 int공간을 만든다면 메모리를 초과하게 되기 때문에

계산만하고 결과로 보여줄 부분만 map 배열에 넣는다.

상용로그를 이용하여 자리수를 확인하고 최대값의 자리수랑 비교하여 예쁘게 출력시켰다.

import java.util.Scanner;

public class BOJ_1022_G4_소용돌이예쁘게출력하기 {

	private static int[][] map;
	private static int[][] dir = { { 0, 1 }, { -1, 0 }, { 0, -1 }, { 1, 0 } };

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int r1 = sc.nextInt();
		int c1 = sc.nextInt();
		int r2 = sc.nextInt();
		int c2 = sc.nextInt();
		// 결과를 담을 배열
		int h = r2 - r1 + 1;
		int w = c2 - c1 + 1;
		map = new int[h][w];

		// 배열에 값 채우기
		int x = 0, y = 0, d = 0, num = 1, cnt = 0, wCnt = 0, dCnt = 1;
		while (true) {
			// 배열을 타 채우면 벗어남
			if(wCnt >= h*w) {
				break;
			}
			if (x >= r1 && x <= r2 && y >= c1 && y <= c2) {
				map[x - r1][y - c1] = num;
				wCnt++;
			}
			num++;
			cnt++;
			x = x + dir[d][0];
			y = y + dir[d][1];
			if (cnt == dCnt) {
				cnt = 0;
				// 좌나 우로 값을 채울때 칸이 하나씩 늘어남
				if (d == 1 || d == 3)
					dCnt++;
				d = (d + 1) % 4;
			}
		}
		// 예쁘게 출력시키기
		int blank = (int)(Math.log10(num)+1);
		for (int i = 0; i < h; i++) {
			for (int j = 0; j < w; j++) {
				int len = (int)(Math.log10(map[i][j])+1);
				for (int k = 0; k < blank-len; k++) {
					System.out.print(" ");
				}
				System.out.print(map[i][j]+" ");
			}
			System.out.println();
		}
	}

}