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

 

1039번: 교환

첫째 줄에 정수 N과 K가 주어진다. N은 1,000,000보다 작거나 같은 자연수이고, K는 10보다 작거나 같은 자연수이다.

www.acmicpc.net


풀이 과정

M자리 숫자 N에서 2개의 숫자의 위치를 K번 바꿨을 때 가능한 최대값을 구하는 문제이다.

 

한 숫자에서 교환해서 만들수 있는 모든 수를 탐색해가면서, K번 교환해서 만들 수 있는 수 중에서 가장 큰 값을 구해주면 된다. 일종의 BFS 문제이다.

 


소스 코드

#include <bits/stdc++.h>
using namespace std;

int N, K, M;

int swap(int num, int a, int b) { // a자리 숫자와 b자리 숫자의 교환
    int aDivisor = pow(10, a);
    int bDivisor = pow(10, b);
    int aNumber = (num / aDivisor) % 10;
    int bNumber = (num / bDivisor) % 10;

    if (aNumber == 0 && b == M-1) return -1;

    return num - (aNumber*aDivisor + bNumber*bDivisor) + (aNumber*bDivisor + bNumber*aDivisor);
}

int main() {
    cin >> N >> K;
    int n = N;

    for (M = 1; M < 7; M++) { // N이 몇자리 수인지 M에 저장
        n /= 10;
        if (n == 0) break;
    }

    priority_queue<int> q[2]; // 최대 힙으로 K번째 교환시 가장 큰 수를 top으로 빠르게 탐색
    int t = 0, nt = 1; // 토글

    q[t].push(N);
    int prev = -1;

    for (int k = 0; k < K; k++) {
        prev = -1;
        while(!q[t].empty()) { // BFS
            int num = q[t].top();
            q[t].pop();

            if (num == prev) continue; // 같은 수를 2번 넣을 필요는 없다
            prev = num;

            int next;
            for (int a = 0; a < M; a++) { // 교환해서 만들 수 있는 모든 수를 힙에 저장
                for (int b = a+1; b < M; b++) {
                    next = swap(num, a, b);
                    if(next != -1) q[nt].push(next);
                }
            }
        }

        t = nt;
        nt = (nt + 1) & 1; // 힙 토글
    }

    if (q[t].empty()) cout << "-1\n";
    else {
        int result = q[t].top();
        cout << result << '\n';
    }

    return 0;
}

'알고리즘 문제 풀이 > 백준' 카테고리의 다른 글

백준 2252 - 줄 세우기 [C++]  (0) 2022.07.12
백준 1717 - 집합의 표현 [C++]  (0) 2022.07.11
백준 1926 - 그림 [C++, 파이썬]  (0) 2022.07.10
백준 1103 - 게임 [C++]  (0) 2022.07.09
백준 3425 - 고스택 [C++]  (0) 2022.07.09

+ Recent posts