문제 링크 : https://www.acmicpc.net/problem/2447
문제
예제를 보고 규칙을 유추한 뒤에 별을 찍어 보세요.
입력
첫째 줄에 N이 주어진다. N은 항상 3의 제곱꼴인 수이다. (3, 9, 27, ...) (N=3^k, 1 ≤ k < 8)
출력
첫째 줄부터 N번째 줄까지 별을 출력한다.
예제 입력
27
예제 출력
풀이
분할 정복 문제이다.
예제 출력을 자세히 보면 가운데가 뻥 뚫린 모양의 직사각형인데
입력으로 주어진 N = 3^k에서 k의 크기가 클수록 직사각형의 규모가 커지고,
그 안에 3^(k-1) 가 9개 존재하는 것을 볼 수 있다. k가 1 증가할 수록 규모가 가로 3 세로 3씩 곱해져서 커지기 때문이다. 따라서 이 문제는 k값을 구하고, k를 인자로 재귀호출할 때마다 사각형을 9등분해 k를 1씩 줄여나가면서 그려주면 된다. 단, 가운데 사각형은 공백 처리를 해줘야한다.
공백 처리부분은 코드를 보며 설명하겠다.
소스 코드
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
39
40
41
42
43
44
45
46
47
48
49
|
#include <iostream>
using namespace std;
char star[2500][2500];
int n;
void put_star(int y, int x, int squard, int check) {
if (squard == 0) {
if (check == 1) star[y][x] = ' ';
else star[y][x] = '*';
return;
}
else {
int t = 1;
for (int i = 0; i < squard - 1; i++) {
t *= 3;
}
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
if (i == 1 && j == 1) put_star(y + (i * t), x + (j * t), squard - 1, 1);
else {
if (check == 1) put_star(y + (i * t), x + (j * t), squard - 1, 1);
else put_star(y + (i * t), x + (j * t), squard - 1, 0);
}
}
}
}
}
void print_star() {
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
printf("%c", star[i][j]);
}
printf("\n");
}
}
int main()
{
scanf("%d", &n);
int squard = 0;
int temp_n = n;
while (temp_n != 1) { //3의 제곱 수 구하기
temp_n /= 3;
squard++;
}
put_star(0, 0, squard, 0);
print_star();
return 0;
}
|
cs |
put_star 함수가 재귀함수 부분이다.
기저사례로 만약 제곱 수가 0이라면 크기가 1x1이므로 출력한다.
공백 부분을 처리하기 위해서 이중 for문으로 재귀호출 시 i = 1, j = 1일 때는 따로 만든 int check를 1로 두고 넘기게 하였고, 기저사례에 도착했을 때 check가 1이면 공백을 넣기로 하였다.
이후에 함수를 계속 재귀하여도 한 번 check가 1이 된건 변하지 않게 하기 위해서 check == 1인건 따로 나누어 처리하도록 하였다.
개발환경 : Visual Studio 2019
지적, 조언 언제든지 환영입니다~~
'백준 문제풀이' 카테고리의 다른 글
백준 11723번 집합 (0) | 2020.01.03 |
---|---|
백준 1074번 Z (0) | 2020.01.02 |
백준 1992번 쿼드트리 (0) | 2020.01.02 |
백준 2263번 트리의 순회 (0) | 2020.01.02 |
백준 1780번 종이의 개수 (0) | 2020.01.02 |