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

 

요새 또 한동안 코드를 만지질 않으니 뭐라도 하고 싶어서 문뜩든 생각이 백준

학교다닐때 가입하고 몇 문제 풀었던거같은데 그 이후로 뭐....

어떻게 이용해야하는지도 잘 모르겠어서 

랜덤 문제 버튼이 있길래 뭐라도 코드를 짜고싶을때 해보자한다.

 

이 문제는 재귀함수를 짜보는 문제인데 

재귀 라는말 답게 스스로 스스로를 부르는 함수이다

1학년때 뎁스그려보면서 강의들었던기억이 아직도 난다.

 

그때 기억이 나는김에 굉장히 오랜만에 c로 해보자고 마음을 먹었고....

코드를 다 짜고난 지금 솔직히 좀 후회된다

 

너무 오랜만에 만져서 기본적인 부분에서 어떻게 하더라? 하고 막혀서 시간이 좀 걸렸다

아무튼 재귀함수는 기본적으로 

A() -> A() -> 이렇게 반복적으로 함수를 부르는 모양으로 잡아야하고 중요한건 탈출시점

탈출이 연쇄적으로 일어나 A1 -> A2 -> A3 -> 탈출! -> A2 -> A1 -> END 이런식으로 된다는걸 알아야한다

 

뭐 그렇게 이 문제는 그런식으로 터미널에 문자를 출력해보는 문제

#include <stdio.h>
#include "q17478.h"

/**
 17478번 재귀함수가 뭔가요?
 */

void _print(int tabCount, const char *msg) {
    // ____
    int prefixSize = 4 * tabCount;
    char prefix[prefixSize+1];
    
    for (int i = 0; i < prefixSize; i ++) {
        prefix[i] = '_';
    }
    // TODO: 문자열 마지막을 직접 체크해줘야 했었나?
    prefix[prefixSize] = '\0';
    
    printf("%s%s\n",prefix, msg);
}


void recursive(int depth, int last) {
    _print(depth, "\"재귀함수가 뭔가요?\"");
    
    // 선인의 답
    if (depth == last) {
        _print(depth, "\"재귀함수는 자기 자신을 호출하는 함수라네\"");
    } else {
        _print(depth, "\"잘 들어보게. 옛날옛날 한 산 꼭대기에 이세상 모든 지식을 통달한 선인이 있었어.");
        _print(depth, "마을 사람들은 모두 그 선인에게 수많은 질문을 했고, 모두 지혜롭게 대답해 주었지.");
        _print(depth, "그의 답은 대부분 옳았다고 하네. 그런데 어느 날, 그 선인에게 한 선비가 찾아와서 물었어.\"");
        int newDepth = depth + 1;
        recursive(newDepth, last);
    }
    _print(depth, "라고 답변하였지.");
    return;
}

void solution(void) {
    int count = 0;
    scanf("%d", &count);
    
    // 도입문
    printf("어느 한 컴퓨터공학과 학생이 유명한 교수님을 찾아가 물었다.\n");
    printf("\"재귀함수가 뭔가요?\"\n");
    
    // 교수님!
    printf("\"잘 들어보게. 옛날옛날 한 산 꼭대기에 이세상 모든 지식을 통달한 선인이 있었어.\n마을 사람들은 모두 그 선인에게 수많은 질문을 했고, 모두 지혜롭게 대답해 주었지.\n그의 답은 대부분 옳았다고 하네. 그런데 어느 날, 그 선인에게 한 선비가 찾아와서 물었어.\"\n");
    
    // 선인과의 대화
    recursive(1, count);
    
    // 교수님 답변 끝!
    printf("라고 답변하였지.\n");
    return;
}

 

생각 나는데로 쭉 적은걸 다시 코드로 옴긴거라 좀 길다

기본적인 문법외로 _print이 함수에서 계속 에러가 났는데

TODO 부분에서 그렇다.

딱히 문자열 끝을 표시해주지 않았던거 같은데, 너무 오래되서 잘 모르겠다

1학년때 배웠으니 십년도 넘은 기억이네 길다길어

 

참고로 sol부분을 좀더 줄일 수 있을듯 한데 잠깐만 하고싶었던게 생각보다 길어지니 고칠의욕이 안난다

나중에 지피티에게 코드리뷰나 받아볼까

 

 

 

+ 추가

쳇지피티에 코드의 개선을 요구해봤다.

#define MAX_DEPTH 50

char PREFIX_BUFFER[4 * (MAX_DEPTH + 1) + 1];   // 최대 깊이 고려한 풀 prefix 버퍼

void build_prefix_buffer(int max_depth) {
    int total = max_depth * 4;
//    for (int i = 0; i < total; i++) {
//        PREFIX_BUFFER[i] = '_';
//    }
    memset(PREFIX_BUFFER, '_', total);
    PREFIX_BUFFER[total] = '\0';
}

void print_prefix(int depth) {
    int size = depth * 4;
    printf("%.*s", size, PREFIX_BUFFER);
}

void recursive(int depth, int last) {
    print_prefix(depth);
    printf("\"재귀함수가 뭔가요?\"\n");

    if (depth == last) {
        print_prefix(depth);
        printf("\"재귀함수는 자기 자신을 호출하는 함수라네\"\n");
    } else {
        print_prefix(depth); printf("\"잘 들어보게. 옛날옛날 한 산 꼭대기에 이세상 모든 지식을 통달한 선인이 있었어.\n");
        print_prefix(depth); printf("마을 사람들은 모두 그 선인에게 수많은 질문을 했고, 모두 지혜롭게 대답해 주었지.\n");
        print_prefix(depth); printf("그의 답은 대부분 옳았다고 하네. 그런데 어느 날, 그 선인에게 한 선비가 찾아와서 물었어.\"\n");

        recursive(depth + 1, last);
    }

    print_prefix(depth);
    printf("라고 답변하였지.\n");
}

void solution(void) {
    int count = 0;
    scanf("%d", &count);

    // prefix 버퍼 준비 (count 만큼만 만들면 됨)
    build_prefix_buffer(count);

    printf("어느 한 컴퓨터공학과 학생이 유명한 교수님을 찾아가 물었다.\n");

    recursive(0, count);
}

더 깊은 뎁스를 표시하기위한 밑줄을 미리 최대한 만들어놓고 필요한만큼만 표시하는건 생각안해봤는데 이렇게도 하구나 싶다

기껏해봐야 재귀 시작할때 미리 그만큼 만들고 하겠지 싶었었는데....

 

오랜만에보는 memset 이건 한번더 요구해서 추가한거다

미리 최대 버퍼까지 만들어두고 하는건 나중에도 또 써먹을 수 있을거같다 기억해둘거다

 

https://github.com/wiwi-git/c-baekjoon/

 

GitHub - wiwi-git/c-baekjoon: 블로그 업데이트용 백준 코드

블로그 업데이트용 백준 코드. Contribute to wiwi-git/c-baekjoon development by creating an account on GitHub.

github.com

 

 

반응형

'C,C++' 카테고리의 다른 글

[C]백준 Q.17427 약수의 합 2  (0) 2025.12.13
[C]백준 Q.1037 약수  (0) 2025.12.12
[C]백준 Q.4375 1  (0) 2025.12.11
[C]백준 Q.2839 설탕 배달  (0) 2025.12.07
[C]백준 Q.1924 2007년  (0) 2025.12.07

+ Recent posts