알고리즘 :: 큰돌 :: Chapter 3 - 완전탐색/백트래킹 :: 백준 2529 부등호

Embedded June·2023년 7월 16일
0
post-thumbnail

문제

문제 링크

해설

  • i - 1번쨰 칸에 고른 숫자와 i - 1번째 부등호가 성립하는 i번쨰 숫자를 고르며 모든 경우의 수를 탐색하는 것이 이 문제의 핵심이었습니다.
  • 선택된 숫자는 모두 달라야 한다는 조건이 있기 때문에,
    • visited[10] 이라는 bool 타입 배열을 만들 수도 있고
    • int 타입 매개변수 1개의 10개 하위 bit를 활용해 현재까지 사용한 숫자를 체크할 수도 있습니다.
    • 저는 후자를 사용했지만, 전자를 사용하셔도 전혀 문제 없습니다.
  • 0번째 칸은 그냥 0부터 9까지 모든 숫자를 넣을 것입니다.
  • 그 전칸과 비교하며 0번째 부등호가 성립하는 숫자부터 차례대로 1번째 칸에 넣습니다.
  • 이 과정을 반복하며 총 K + 1개의 숫자를 선택합니다.
    • min(), max() 함수를 이용해서 최댓값과 최솟값을 구할 수 있습니다.
    • 왜냐하면, 모든 숫자가 K + 1 자리수로 똑같기 때문에 단순 문자열 비교 == 숫자 비교이기 때문입니다.
      • (주의하세요! 자릿수가 동일하다는 보장이 없다면 문자열 비교 ≠ 숫자 비교 입니다. 예를 들어 11111 보다 12가 문자열로는 더 큽니다.)

코드

#include <iostream>
using namespace std;

int K;
char sign[10];
string answer_max = "000000000", answer_min = "9999999999";

void solve(string num, int hash, int cnt)
{
    if (cnt == K + 1) {
        answer_max = max(answer_max, num);
        answer_min = min(answer_min, num);
        return;
    }
    for (int i = 0; i < 10; i++) {
        if (hash & (1 << i)) continue;
        int idx = cnt - 1;
        if (cnt == 0 || 
            (sign[idx] == '<' && (num.back() - '0') < i) ||
            (sign[idx] == '>' && (num.back() - '0') > i))
                solve(num + static_cast<char>(i + '0'), hash | (1 << i), cnt + 1);
    }
}

int main()
{
    ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
    cin >> K;
    for (int i = 0; i < K; i++) cin >> sign[i];
    solve("", 0, 0);
    cout << answer_max << '\n' << answer_min << '\n';
    return 0;
}

소스코드 링크

결과

profile
임베디드 시스템 공학자를 지망하는 컴퓨터공학+전자공학 복수전공 학부생입니다. 타인의 피드백을 수용하고 숙고하고 대응하며 자극과 반응 사이의 간격을 늘리며 스스로 반응을 컨트롤 할 수 있는 주도적인 사람이 되는 것이 저의 20대의 목표입니다.

0개의 댓글