[알고리즘] 백준 1039

shininghyunho·2021년 7월 6일
0

문제


N,K가 주어졌을때 N의 자리수를 K번 교환해보며 K번째 최대값을 구하는 문제다.

단순히 BFS를 통해 가지를 이어나가면 경의의 수가 굉장히 많아진다.
6숫자중 2개를 뽑으면 15인데 이게 10번 반복하면 15^10이다.

너무 큰 숫자이기에 가지를 적절하게 쳐줘야한다.

핵심은 각 스텝에서 중복을 없애는 것이다.
매 단계에서 중복을 없애면 해결할 수 있었다.
(또한 삼성문제처럼 안되는 조건을 찾는게 까다롭다.)

code

/*
백준 1039
10^6 이 최대값인데 결국은 6! = 720가지다
근데 visited를 다시 방문해야하지 않나..?
*/
#include <iostream>
#include <queue>
#include <map>
using namespace std;

int N, K,N_len;

int numLen(int num) {
	int res = 0;
	while (num != 0) {
		res++;
		num /= 10;
	}
	return res;
}

bool isOk() {
	// 1. 1자리
	if (N_len == 1)	return false;

	// 2. 2자리인데 1자리가 0인 경우
	if (N_len == 2 && (N % 10 == 0)) return false;

	return true;
}

int toNum(char arr[]) {
	int res = 0;
	for (int i = 0; arr[i]; i++) {
		res *= 10;
		res += arr[i] - '0';
	}
	return res;
}

int swapNum(int num, int l, int r) {
	char buf[16];
	sprintf(buf, "%d", num); // num을 buf에 넣게됨

	// swap
	char tmp;
	tmp = buf[l];
	buf[l] = buf[r];
	buf[r] = tmp;

	// 바꾼값이 0으로 시작하면 -1 반환
	if (buf[0] == '0') return -1;

	return toNum(buf);
}

int main(){
	cin >> N >> K;
	queue<int> que;
	map<int, int> map;
	que.push(N);

	// 처음부터 교환이 불가능한 경우 바로 출력
	N_len = numLen(N);
	if (!isOk()) {
		cout << -1;
		return 0;
	}
	for (int i = 0; i < K; i++) {
		int que_sz = que.size();
		map.clear(); // 각 스탭마다 중복 체크
		// 교환 진행
		for (int j = 0; j < que_sz; j++) {
			int num = que.front();
			que.pop();
			// N자리 중에서 2개를 골라 교환 (0,1) (0,2) ... (lastIdx-1,lasIdx)
			for (int a = 0; a < N_len - 1; a++) {
				for (int b = a + 1; b < N_len; b++) {
					int next_num = swapNum(num, a, b);
					if (next_num == -1) continue; // 불가능하면 패스
					if (map.find(next_num) != map.end()) continue; // 중복되면 패스
					map.insert({ next_num,next_num });
					//printf("[%d] %d\n", i, next_num);
					que.push(next_num);
				}
			}
		}
	}
	// que가 비어있으면 -1
	if (que.empty()) {
		cout << -1;
		return 0;
	}
	// que 안에서 최대값 출력
	int max_val = -int(1e9);
	while (!que.empty()) {
		int num = que.front();
		que.pop();
		max_val = (num>max_val) ? num : max_val;
	}
	cout << max_val;
	return 0;
}
profile
shining itself

0개의 댓글

관련 채용 정보