본문 바로가기
알고리즘

백준 2447 g5 별 찍기 - 10 c++

by kyj0032 2024. 1. 13.

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