반응형
LinkedIn 개발자로 성장하면서 남긴 발자취들을 확인하실 수 있습니다.
Github WWDC Student Challenge 및 Cherish, Tiramisul 등 개발한 앱들의 코드를 확인하실 수 있습니다.
개인 앱 : Cherish 내 마음을 들여다보는 시간, 체리시는 디자이너와 PM과 함께 진행 중인 1인 개발 프로젝트입니다.
10년 후, 20년 후 나는 어떤 스토리 텔러가 되어 있을지 궁금하다. 내가 만약에 아직 조금 더 탐구하고 싶은 게 있고, 궁금한 게 있다면, 그게 설사 지금 당장의 내 인생에 도움이 안 되는 것 같더라도 경험해보자. 그 경험들을 온전히 즐기며 내 것으로 만들고, 내 일에 녹여내고... 그러다보면 그 점들이 모여 나란 사람을 그려내는 선이 될 테니까.

Recent Posts
Recent Comments
Total
관리 메뉴

꿈꾸는리버리

[백준 알고리즘] 2447 별 찍기 - 10 본문

오뚝이 개발자/알고리즘

[백준 알고리즘] 2447 별 찍기 - 10

rriver2 2021. 12. 3. 14:02
반응형

 재귀 

: 원래의 자리로 되돌아가거나 되돌아옴

다시 자신의 함수를 호출하는 것을 재귀 함수라고 생각하면 쉽다.

 

재귀 함수를 작성할 때 중요한 것이 2가지가 있다.

1. base case를 만들 것

2. 스택이 줄어들어야 할 것

 

제:    

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

 

2447번: 별 찍기 - 10

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

www.acmicpc.net

풀이방법:    

key point : 한칸 한칸이 " "일지, "*"일지 판별해내야 한다!

 

우선 N = 3일 때 부터 생각해보자.

N =3

빈 칸은 (1,1)로 i%3 ==1이면서 j%3 ==1인 부분이다.

 

다음으로 N = 9일 때를 생각해보자.

N = 9

 

빨간 동그라미 부분과 핑크 동그라미 부분을 나눠서 생각해보자.

빨간 동그라미 부분에서는  i%3 ==1이면서 j%3 ==1인 경우이고,

핑크 동그라미 부분에서는  i/3%3 ==1이면서 j/3%3 ==1인 경우이다.

 

다음으로 N = 27일 때를 생각해보자.

N = 27

파란 동그라미 부분과 빨간 동그라미 부분과 핑크 동그라미 부분을 나눠서 생각해보자.

파란 동그라미 부분에서는  i%3 ==1이면서 j%3 ==1인 경우이고,

빨간 동그라미 부분에서는  i/3%3 ==1이면서 j/3%3 ==1인 경우이고,

핑크 동그라미 부분에서는  i/3/3%3 ==1이면서 j/3/3%3 ==1인 경우이다.

 

만약 재귀를 쓰지 않는다면 

for문 i,j

if(i%3 ==1 && j%3 ==1){

print " "

}else f(i/3%3 ==1 && j/3%3 ==1){

print " "

}else f(i/3/3%3 ==1 && j/3/3%3 ==1){

print " "

} ... 

else{

print "*"

}

-->  N=3^k이며, 이때 1 ≤ k < 8 라고 했으니까 이 과정을.. 3^k..... ㅎ... 아닌거 같죵 ?

 

그래서 재귀를 사용해야 한다..!

 

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

 

재귀함수 호출 부분)

star(i/3, j/3, N/3)이 다시 호출된다.

만약에 i % 3 == 1 && j % 3 == 1 이게 아니라면

이제 다음으로는 i/3%3 ==1 && j/3%3 ==1을 검사해야 한다.

그렇기 때문에 star의 다음 i, j 값은 i/3, j/3이다.

N이 3의 거듭제곱(3, 9, 27, ...) 이기 때문에 당연히 한단계 내려갈 때도 N-1이 아니라 N/3이 되겠죠..?

따라서 나머지는 star(i/3, j/3, N/3)으로 넘어간다. 

이 과정이 반복이 되면서 N=1이 될 때까지 " "의 케이스가 있는지 확인한다. 

 

ex) N= 27에서 (4,8)을 생각해보자.

star(4, 8, 27)이 메인에서 호출이 되면,

star(1,2,9) -> star(1,2,3) -> star(1,2,1) -> "*"출력

 

ex) N= 27에서 (10,11)을 생각해보자.

star(10,11, 27)이 메인에서 호출이 되면,

star(3,3,9) -> star(1,1,3) -> " "출력

 

작성한 코드는 다음과 같다.

#include <iostream>
using namespace std;

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

int main() {
    int N;
    cin >> N;
    for(int j = 0; j < N;j++){
        for(int i = 0; i < N;i++){
            star(i,j,N);
        }
        cout << "\n";
    }
    return 0;
}

성공한 사진!    

 

MEMO

시험기간에 이게 뭐하는 건지,, 최근들어 제일 어려운 문제였다. 재귀는 학교에서 배울때도 알듯 모를듯 알듯 모른다. 그래도 열심히 규칙을 찾고 정리를 해보니까 이해가 되었다. 

반응형
Comments