프로그래밍 공부/백준 (C++)

[C++ / 백준 1248번] Guess(맞춰봐)

Rocketbabydolls 2025. 2. 5. 15:56

 

백트래킹을 이용해 푸는 문제.

늘상 하던 백트래킹 말고 좋아보이는 방법을 하나 발견할 수 있었는데, 처음에는 N^2 시간복잡도로 풀이하려 했었다.
그 대신 Sum 배열을 선언한 후 합을 미리 구해 놓는 방식이다. 이를 통해 시간복잡도를 획기적으로 줄일 수 있다.
원하는 범위(-10 ~ 10) 까지에서 원하는 Depth 까지 순열을 구한다.
(1, 1), (2,2) (3,3)  ----  이렇게 i == j 일 때는 무조건 자기 자신을 검사하면 되므로

 

if ((sign[depth][depth] == '+' && i <= 0) ||
    (sign[depth][depth] == '-' && i >= 0) ||
    (sign[depth][depth] == '0' && i != 0)) {
    continue;
}

 

이렇게 복잡도를 줄일 수 있다.

그리고 recur() 함수로 재귀 호출을 하기 전에 check() 로 유효성을 검사했다. (훨씬 효율적인 방법이다.)

삼항 연산자 이용

두 번의 삼항 연산자 이용이 있었는데,

 

     sum[depth] = (depth > 0 ? sum[depth - 1] : 0) + i;

 

int tmp = sum[depth] - (i > 0 ? sum[i - 1] : 0);

 

이렇게 두 번이다.

시간 복잡도를 1까지 줄일 수 있는 좋은 방법으로 애용해야겠다.

 

 

#include <iostream>
#include <vector>
using namespace std;

char sign[10][10];

vector<int> seq;
int N;

int sum[10] = { 0 };

bool check(int depth)
{
 
    for (int i = 0; i < depth; i++)
    {

        int tmp = sum[depth] - (i > 0 ? sum[i - 1] : 0);


        if ((tmp >= 0 && sign[i][depth] != '+') ||
            (tmp <= 0 && sign[i][depth] != '-') ||
            (tmp == 0 && sign[i][depth] != '0'))
        {
            return false;
        }

    }
    return true;

}


void recur(int depth)
{
    if (depth == N)
    {
            for (auto i : seq)
            {
                cout << i << " ";
            }
            exit(0);
     
        return;
    }


    for (int i = -10; i <= 10; i++)
    {
        if ((sign[depth][depth] == '+' && i <= 0) ||
            (sign[depth][depth] == '-' && i >= 0) ||
            (sign[depth][depth] == '0' && i != 0)) {
            continue;
        }

            seq.push_back(i);
            sum[depth] = (depth > 0 ? sum[depth - 1] : 0) + i;

            if(check(depth))
                recur(depth + 1);

            seq.pop_back();
            
    }
}


int main()
{
    cin >> N;

    for (int i = 0; i < N; i++)
    {
        for (int j = i; j < N; j++)
        {
            cin >> sign[i][j];
        }
    }

    recur(0);   


    return 0;
}