카테고리 없음

[BOJ1022/Java] 소용돌이 예쁘게 출력하기

IT 참다랑어 2023. 9. 22. 08:21

1. 문제 요약
정해진 규칙에 따라서 그려지는 소용돌이가 있고 그 중에서 필요한 부분만을 찾아 출력하는 문제이다

2. 입/출력
문제 제한범위가 조금 특이하다.
r1,c1,r2,c2가 가질 수 있는 값은 넓지만
r2-r1, c2-c1이 가질 수 있는 값은 작다.

3.
만약 값들이 가질 수 있는 값의 최대범위에 맞춰서 배열 사이즈를 정하면 메모리 초과가 발생한다. 따라서 딱 필요한 만큼만 저장하는 것이 필요하다.

그래서 생각한 풀이 방법은 정해진범위까지 숫자를 탐색하는데 기록할 위치만 기록하자 이다.
중앙부에서부터 수를 늘리면서 범위안에 있으면 배열에 쓰고 아니면 말기!

4. 구현 코드

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

public class Main {

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

	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st = new StringTokenizer(br.readLine());
  int r1 = Integer.parseInt(st.nextToken());
		int c1 = Integer.parseInt(st.nextToken());
		int r2 = Integer.parseInt(st.nextToken());
		int c2 = Integer.parseInt(st.nextToken());
		// 결과를 담을 배열
		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();
		}
	}

}