반응형

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

 

2448번: 별 찍기 - 11

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

www.acmicpc.net

 

  • 문제 이해
  • 해결 방법
  • 구현 코드

문제 이해

 

이전에 풀었던 별 찍기 - 10번 문제와 비슷한 형태였다.

3 * 2^N을 (3, 6, 12, 24, 48...)인 수를 입력받아서 삼각 형안에 삼각형 형태로 별을 재귀적으로 찍으면 된다.

 

문제의 예제로 봤을 때 입력된 수는 높이가 되고, 너비는 높이 * 2인 것을 알아챌 수 있었다.

그리고 대략적으로 윗 삼각형은 현재 높이의 2로 나누어지는 부분이고, 아랫 삼각형 두개는 현재 너비를 2로 나누어

두 부분으로 나누어져 재귀적으로 그려지는 것을 대략적으로 파악한 후 문제 해결 방법을 생각하였다.

 

 


해결 방법

 

처음 생각은 정가운데에 어떻게 index를 찾아서 별을 찍을까 고민하다가 가장 작은 삼각형의 형태인

높이가 3일때에 높이와 너비 index에 빼는 방식으로 별을 찍으면 찍을 수 있을 것 같았고 그 방법으로

별을 찍어 문제를 해결했다. 그러므로 재귀 함수의 종료 조건은 높이가 3이므로 size가 3일 때 종료되게끔 하였다.

 

이러한 문제 유형은 2차원 배열을 입력의 크기만큼 생성해두고 index 조정만 잘해준다면 문제없이 풀 수 있는 문제이다.

가장 오른쪽 끝, 맨 밑의 index를 알아내어 그 부분부터 index를 빼서 별을 찍을 생각이었으므로

끝 값 index에 현재 해당되는 size만큼 빼주면 쉽게 재귀적으로 높이와 너비 부분을 인자로 넣어 재귀 함수를 호출할 수 있다.

 

가장 먼저 재귀 함수내에서 현재 size를 2로 나누어 간격으로 활용하였다.

예를 들어 24가 입력으로 들어오면 간격은 12가 되어 현재 간격으로 높이와 너비를 적절히 빼주면 된다.

 

가장 윗 삼각형은 높이가 반으로 줄어드므로 현재 높이(24) - 간격(12)으로 처리해주었다.

너비는 총 48이고 4분의3 지점이 오른쪽 끝이 되므로 현재 너비(48) - 간격(12)으로 처리했다.

 

아래 두개의 삼각형은 높이는 가장 아래를 사용할 것이기 때문에 그대로 사용하고,

너비는 현재 너비(48) - 간격 * 2(24)로 첫 번째 아래 삼각형을 재귀 호출하고,

두 번째 아래 삼각형은 높이와 너비를 그대로 사용하면 되었다.

 

종료 조건에서 별을 찍을 때는 높이와 너비가 가장 아래, 가장 오른쪽이 들어왔으므로 적절히 빼주어 삼각형을 그려주게끔 하였다.

index는 크기를 기준으로 사용했으므로 -1을 추가로 더해주면 알맞게 찍힌다.

 

출력을 할 때 System.out.println()을 쓰면 시간초과가 걸려서 BufferedWriter를 사용했다.

 


구현 코드

 

import java.io.*;
import java.util.*;
 
public class Main {
    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    static BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
    static int N;
    static String[][] stars;
 
    public static <stars> void main(String[] args) throws IOException {
        int N = Integer.parseInt(br.readLine());
        stars = new String[N][N*2];
        for(int i = 0; i<stars.length; i++){
            for(int j = 0; j<stars[i].length; j++){
                stars[i][j] = " ";
            }
        }
        
        recur(N, N*2, N);
 
        for(int i = 0; i<stars.length; i++){
            for(int j = 0; j<stars[i].length; j++){
                bw.write(stars[i][j]);
            }
            bw.write("\n");
        }
        bw.flush();
        bw.close();
    }
    public static void recur(int h, int w, int size){
        if(size == 3){
            stars[h-3][w-4= "*";
 
            stars[h-2][w-3= "*";
            stars[h-2][w-5= "*";
 
            stars[h-1][w-2= "*";
            stars[h-1][w-3= "*";
            stars[h-1][w-4= "*";
            stars[h-1][w-5= "*";
            stars[h-1][w-6= "*";
            return;
        }
 
        // 간격
        size /= 2
 
        // 윗 삼각형 1개
        recur(h - size, w-size, size);
 
        // 아랫 삼각형 2개
        recur(h, w - size * 2, size); 
        recur(h, w, size);
    }
}
 
 
cs

 

출력 결과

 

반응형

+ Recent posts