https://www.acmicpc.net/problem/2447
재귀적인 패턴으로 별을 찍어 보자. 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이며, 이때 1 ≤ k < 8이다.
첫째 줄부터 N번째 줄까지 별을 출력한다.
재귀를 잘 이용하여 좌표값에 따라 경우를 나누어 푸는 문제였다.
재귀는 크게 가운데 부분과 가운데가 아닌 부분 2가지로 나눌 수 있다. 9개의 영역 중에서 가운데 부분만 공백 문자를 입력시키고 나머지 부분은 *을 출력하면 된다.
영역을 9개로 나누었을 때 가운데를 제외한 나머지 8개 영역은 모양이 같으므로 좌표값을 검사할 때 (0,0)부터 시작하는 왼쪽 위로 기준을 맞추어 재귀를 실행한다.
따라서 재귀를 할 때, 현재 가로 세로 크기인 N에 3을 나누어주고 모든 영역의 좌표값을 왼쪽 위의 사각형 기준으로 수정한다.
이때, 가운데 부분만 bool 등을 이용해 차별점을 두어 바로 공백을 출력하도록 한다.
#include <iostream>
using namespace std;
void recurse(int x, int y, int size, bool flag) {
if (flag) {
cout << " ";
return;
}
if (size == 1) {
cout << "*";
return;
}
if (x < size / 3 && y < size / 3) {
recurse(x, y, size / 3, false);
}
else if (x < size / 3 && y >= size / 3 && y < size / 3 * 2) {
recurse(x, y - size / 3, size / 3, false);
}
else if (x < size / 3 && y >= size / 3 * 2) {
recurse(x, y - size / 3 * 2, size / 3, false);
}
else if (x >= size / 3 && x < size / 3 * 2 && y < size / 3) {
recurse(x - size / 3, y, size / 3, false);
}
else if (x >= size / 3 && x < size / 3 * 2 && y >= size / 3 && y < size / 3 * 2) {
recurse(x - size / 3, y - size / 3, size / 3, true);
}
else if (x >= size / 3 && x < size / 3 * 2 && y >= size / 3 * 2) {
recurse(x - size / 3, y - size / 3 * 2, size / 3, false);
}
else if (x >= size / 3 * 2 && y < size / 3) {
recurse(x - size / 3 * 2, y, size / 3, false);
}
else if (x >= size / 3 * 2 && y >= size / 3 && y < size / 3 * 2) {
recurse(x - size / 3 * 2, y - size / 3, size / 3, false);
}
else if (x >= size / 3 * 2 && y >= size / 3 * 2) {
recurse(x - size / 3 * 2, y - size / 3 * 2, size / 3, false);
}
}
int main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
int N;
cin >> N;
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
recurse(i, j, N, false);
}
cout << "\n";
}
return 0;
}