728x90
728x90

문제

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

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

***
* *
***

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

 

입력

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

 

출력

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

 

예제 입력 1 

27

 

예제 출력 1 

***************************
* ** ** ** ** ** ** ** ** *
***************************
*** ****** ****** ***
* * * ** * * ** * * *
*** ****** ****** ***
***************************
* ** ** ** ** ** ** ** ** *
***************************
********* *********
* ** ** * * ** ** *
********* *********
*** *** *** ***
* * * * * * * *
*** *** *** ***
********* *********
* ** ** * * ** ** *
********* *********
***************************
* ** ** ** ** ** ** ** ** *
***************************
*** ****** ****** ***
* * * ** * * ** * * *
*** ****** ****** ***
***************************
* ** ** ** ** ** ** ** ** *
***************************

 

알고리즘 분류

  • 분할 정복
  • 재귀

 

문제 출처

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

 

2447번: 별 찍기 - 10

재귀적인 패턴으로 별을 찍어 보자. N이 3의 거듭제곱(3, 9, 27, ...)이라고 할 때, 크기 N의 패턴은 N×N 정사각형 모양이다. 크기 3의 패턴은 가운데에 공백이 있고, 가운데를 제외한 모든 칸에 별이

www.acmicpc.net

 


 

문제 해결 방법

  • 위의 문제는 프랙탈(Fractal) 도형 문제와 연관이 있다.
프랙탈 도형의 예
  • 프랙탈 도형 문제는 보통 분할 정복(Divide and Conquer) 기법을 이용하여 해결할 수 있다.

 

기본 패턴 분석하기

***
* *
***
  • N = 3일 때 나타나는 기본적인 패턴을 좌표계를 이용하여 분석해본다.
  0 1 2
0 * * *
1 *   *
2 * * *
  • 비어 있는 부분의 좌표는 (1, 1)로 표현할 수 있다.
  • 다음과 같은 경우에는 비어 있는 좌표는 (1, 1), (4, 1), (7, 1)로 표현할 수 있다.
  0 1 2 3 4 5 6 7 8
0 * * * * * * * * *
1 *   * *   * *   *
2 * * * * * * * * *
  • 따라서 가장 기본적인 패턴을 만족시키기 위한 조건은 다음과 같다.
i % 3 == 1 && j % 3 == 1

 

응용 하기

  • N = 9일 때 나타나는 패턴을 분석해본다.
  0 1 2
0 1 2 3 4 5 6 7 8
0 0 * * * * * * * * *
1 *   *   *   *   *
2 * * * * * * * * *

1

3 * * *       * * *
4 *   *       *   *
5 * * *       * * *

2

6 * * * * * * * * *
7 *   * *   * *   *
8 * * * * * * * * *
  • N = 3일 때의 기본 패턴의 크기가 커진 형태를 띄는 것을 확인할 수 있다.
  • 가운데 부분의 비어있는 좌표는 (3, 3), (3, 4), (3, 5), (4, 3), (4, 4), (4, 5), (5, 3), (5, 4), (5, 5)이다.
  • 중앙의 비어 있는 곳들은 다음과 같이 일반화하여 표현할 수 있다.
(i / 3) % 3 == 1 && (j / 3) % 3 == 1

 

 알고리즘 작성하기

void printStar(int i, int j, int n) {
if ((i / n) % 3 == 1 && (j / n) % 3 == 1) {
cout << " ";
}
else {
if (n / 3 == 0) {
cout << "*";
}
else {
printStar(i, j, n / 3);
}
}
}

 

코드

#include <iostream>
using namespace std;
void printStar(int i, int j, int n) {
if ((i / n) % 3 == 1 && (j / n) % 3 == 1) {
cout << " ";
}
else {
if (n / 3 == 0) {
cout << "*";
}
else {
printStar(i, j, n / 3);
}
}
}
int N;
int main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
cin >> N;
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
printStar(i, j, N);
}
cout << '\n';
}
return 0;
}

 

채점 결과

 

참고

  • [단계별로 풀어보기] > [재귀]
  • 골드V

 

728x90
728x90

문제입력출력예제 입력 1 예제 출력 1 알고리즘 분류문제 출처문제 해결 방법기본 패턴 분석하기응용 하기 알고리즘 작성하기코드채점 결과참고