Home [2447] 별 찍기 - 10
Post
Cancel

[2447] 별 찍기 - 10

문제 링크 : https://www.acmicpc.net/problem/2447

2447 - 별 찍기 10

본문

재귀적인 패턴으로 별을 찍어 보자. $N$이 3의 거듭제곱(3, 9, 27, …)이라고 할 때, 크기 $N$의 패턴은 $N\times N$ 정사각형 모양이다.

크기 3의 패턴은 가운데에 공백이 있고, 가운데를 제외한 모든 칸에 별이 하나씩 있는 패턴이다.

1
2
3
***
* *
***

$N$이 3보다 클 경우, 크기 $N$의 패턴은 공백으로 채워진 가운데의 $(N/3) \times (N/3)$ 정사각형을 크기 $N/3$의 패턴으로 둘러싼 형태이다. 예를 들어 크기 27의 패턴은 예제 출력 1과 같다.

입력

첫째 줄에 $N$이 주어진다. $N$은 3의 거듭제곱이다. 즉 어떤 정수 $k$에 대해 $N=3^k$이며, 이때 $1 \leq k < 8$이다.

출력

첫째 줄부터 $N$번째 줄까지 별을 출력한다.

제한

시간 제한메모리 제한
1sec256MB

풀이

사용하는 패턴의 모양이 1종류밖에 없다. 3x3 크기의 공간에서 중앙을 제외하고 다 켜버리면 된다. 그리고 켜진 칸에서도 중앙만 비우는 식으로 계속 진행하는 것을 알 수 있다. 재귀함수로 구현하면 쉽게 해결할 수 있다.

재귀함수는 규칙과 exit point만 잘 잡아주면 된다. 하나씩 생각해보면 아래와 같을 것이다.

  • 규칙은 3x3 크기의 공간에서 중앙을 제외한 나머지 부분들을 on시키는 것
  • exit point는 $n = 3^0 = 1$일 때, 호출되는 경우 그 칸은 켜진 칸이므로 ‘*‘을 나타냄

이 규칙을 적용하여 함수를 구현하면 된다.

  • 참고 알고리즘 :

코드

사용 언어 : C

최종 수정일 : 2023 / 3 / 30

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include <stdio.h>

#define MAX_IDX (6561 + 1)
char grid[MAX_IDX][MAX_IDX];

const int false = 0;

void getStar(int x, int y, int n) {
    if (n == 1) {
        grid[x][y] = '*';
    } else {
        for (int i = 0; i < 3; ++i) {
            for (int j = 0; j < 3; ++j) {
                if ((i == 1 && j == 1) == false) {
                    getStar(x + (n / 3) * i, y + (n / 3) * j, n / 3);
                }
            }
        }
    }
    return;
}

int main() {
    int n;
    scanf("%d", &n);
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < n; ++j) {
            grid[i][j] = ' ';
        }
        grid[i][n] = '\0';
    }

    getStar(0, 0, n);
    for (int i = 0; i < n; ++i) {
        printf("%s\n", grid[i]);
    }
    return 0;
}
This post is licensed under CC BY 4.0 by the author.