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

풀이
그냥 재귀로 찍으면 되는 것이 아니라, 프린터처럼 한 줄씩 찍어야하기 때문에 \n 개행 처리가 복잡하다.
어쨌거나 한 줄마다 찍어야 하므로, 한 줄 단위로 재귀적으로 생각해봤다
N=3 일 때,
*** <- g(3, 0)
* * <- g(3, 1)
*** <- g(3, 2)
으로 각각 칭하겠다
N=9 기준으로 생각해보면,
1번째 줄 -> g(3, 0) * 3개 // *** *** **
2번째 줄 -> g(3, 1) * 3개 // * * * * * *
3번째 줄 -> g(3, 2) * 3개 // *** *** ***
4번째 줄 -> g(3, 0), 공백*3, g(3, 0)
5번째 줄 -> g(3, 1), 공백*3, g(3, 1)
6번째 줄 -> g(3, 2), 공백*3, g(3, 2)
...
1번째 줄에는 변 길이가 3인 정사각형의 첫번째 줄이 3개,
2번째 줄에는 변 길이가 3인 정사각형의 두번째 줄이 3개, ... 이런 식으로 반복된다.
다만 세로를 3부분으로 나눴을 때, 가운데 부분의 가운데는 공백을 출력해야 한다.
수도 코드
f(n) {
for(r: 0줄 부터~n-1줄까지)
g(n, r)
출력 \n
}
g(n, r) {//한 변이 n인 정사각형의 r번째 줄
if 중간이 아니면
g(n/3, r%3) * 3번 반복
else // 중간이면 중간에 빈 공간을 띄워야함
g(n/3, r%3), 공백 * n/3, g(n/3, r%3)
}
코드
/*boj g5 2447 별 찍기 5*/
#include <iostream>
using namespace std;
int N;
void g(int n, int r) {
if (n == 3) {
if (r == 0 || r == 2)
cout << "***";
else if (r == 1)
cout << "* *";
return;
}
if (r >= n / 3 && r < (n / 3) * 2) {
g(n / 3, r % (n / 3));
for (int i = 0; i < n / 3; i++)
cout << ' ';
g(n / 3, r % (n / 3));
} else {
g(n / 3, r % (n / 3));
g(n / 3, r % (n / 3));
g(n / 3, r % (n / 3));
}
}
void f(int n) {
for (int i = 0; i < n; i++) {
g(n, i);
cout << '\n';
}
}
int main(void) {
ios::sync_with_stdio(0);
cin.tie(0);
cin >> N;
f(N);
}
이전에는 그냥 배열을 만들어서 저장하는 형식으로 했었다
2년 전에 비해 그래도 발전했구나 ..
'알고리즘' 카테고리의 다른 글
백준 s3 15649 N과 M (1) c++ (0) | 2024.01.15 |
---|---|
백준 g5 2448 별 찍기 - 11 c++ (0) | 2024.01.13 |
백준 s1 1074 Z c++ (0) | 2024.01.13 |
백준 g5 11729 하노이 탑 이동 순서 c++ (0) | 2024.01.13 |
백준 s1 1629 곱셈 c++ (0) | 2024.01.13 |