티스토리 뷰

728x90
반응형

백준 온라인 저지(BOJ) 2448번 별찍기 - 11

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

 

2448번: 별 찍기 - 11

첫째 줄에 N이 주어진다. N은 항상 3×2k 수이다. (3, 6, 12, 24, 48, ...) (0 ≤ k ≤ 10, k는 정수)

www.acmicpc.net

* 사용언어 : java, 자바

 

1. 문제

N( = 3 * 2 ^ k(1, 2, ... , 10) )을 입력받고

N번째 줄까지 예제와 같이 별을 출력

 

2. 풀이

함수 사용하기 카테고리에 속해있지만,

함수로 기능을 나누는게 중요한 문제는 아닌 것 같습니다.

(그래도 함수를 사용하여 작성하긴 했습니다)

 

알고리즘 문제를 풀 때 문제가 잘 이해가 안되면 한 번에 다 해결하려 하지 말고,

1) 일부 조건을 제외하거나

2) 가장 단순한 입력값부터 한 단계씩 해결

하는 방식으로 접근해보면 문제를 이해하는데 도움이 됩니다.

저는 2)와 같은 방식으로 접근하여 문제를 풀었습니다.

 

(1) k = 1 (N = 3) 일때,

이 3줄은 억지로 규칙을 찾기보단 문자열 그대로 출력하는 쪽이 나을 것 같습니다.

 

(2) k = 2 (N = 6) 일때,

k = 1 일때의 모양을 그대로 가져와서 만드는 법을 생각해봤습니다.

새롭게 추가된 아랫줄 삼각형(i = 3, 4, 5) 은 아래와 같이 만들 수 있습니다.

i = 3의 문자열은 [k = 1일때의 i = 0 의 문자열] + [공백] + [k = 1일때의 i = 0 의 문자열]

i = 4의 문자열은 [k = 1일때의 i = 1 의 문자열] + [공백] + [k = 1일때의 i = 1 의 문자열]

i = 5의 문자열은 [k = 1일때의 i = 2 의 문자열] + [공백] + [k = 1일때의 i = 2 의 문자열]

이런 식으로 입니다.

그 후 기존 삼각형(i = 0, 1, 2) 은 양 옆에 [3칸의 공백]을 추가합니다.

 

(3) k = 3 (N = 12) 일때,

마찬가지로 k = 2 일때의 모양을 그대로 가져와서 만드는 법을 생각해봤습니다.

새롭게 추가된 아랫줄 삼각형(i = 6, 7, 8, ..., 11) 은 아래와 같이 만들 수 있습니다.

i = 6의 문자열은 [k = 2일때의 i = 0 의 문자열] + [공백] + [k = 2일때의 i = 0 의 문자열]

i = 7의 문자열은 [k = 2일때의 i = 1 의 문자열] + [공백] + [k = 2일때의 i = 1 의 문자열]

i = 8의 문자열은 [k = 2일때의 i = 2 의 문자열] + [공백] + [k = 2일때의 i = 2 의 문자열]

...

i = 11의 문자열은 [k = 2일때의 i = 5 의 문자열] + [공백] + [k = 2일때의 i = 5 의 문자열]

이런 식으로 입니다.

그 후 기존 삼각형(i = 0, 1, 2, ..., 5) 은 양 옆에 [6칸의 공백]을 추가합니다.

 

이런 식으로 규칙을 찾을 수 있었고, 이를 일반화하여 코드를 작성했습니다.

위에서 설명한 과정은 makeBigStar(int k, string map[]) 라는 메서드로 구현했습니다.

 

3. 코드

import java.util.Scanner;

public class Main {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt();
		sc.close();

		String map[] = new String[n];
		map[0] = "  *  ";
		map[1] = " * * ";
		map[2] = "*****";
        
		for (int k = 1; 3 * (int)Math.pow(2, k) <= n; ++k) {
			makeBigStar(k, map);
		}
		for (int i = 0; i < n; ++i) {
			System.out.println(map[i]);
		}
	}

	private static void makeBigStar(int k, String map[]) {
		int bottom = 3 * (int)Math.pow(2, k);
		int middle = bottom / 2;
		for (int i = middle; i < bottom; ++i) {
			map[i] = map[i - middle] + " " + map[i -middle];
		}
		String space = "";
		while (space.length() < middle) {
			space += " ";
		}
		for (int i = 0; i < middle; ++i) {
			map[i] = space + map[i] + space;
		}
	}
}
728x90
반응형
댓글