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$번째 줄까지 별을 출력한다.
제한
시간 제한 | 메모리 제한 |
---|---|
1sec | 256MB |
풀이
사용하는 패턴의 모양이 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;
}