새소식

PS/백준

[백준/1039] 교환 (Python)

  • -

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

 

1039번: 교환

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

www.acmicpc.net

 

Difficulty : Gold 2

 

Status : Solved

 

Time : 00:10:08

 


 

문제 설명

 

더보기

 

0으로 시작하지 않는 정수 N이 주어진다. 이때, M을 정수 N의 자릿수라고 했을 때, 다음과 같은 연산을 K번 수행한다.

1 ≤ i < j ≤ M인 i와 j를 고른다. 그 다음, i번 위치의 숫자와 j번 위치의 숫자를 바꾼다. 이때, 바꾼 수가 0으로 시작하면 안 된다.

위의 연산을 K번 했을 때, 나올 수 있는 수의 최댓값을 구하는 프로그램을 작성하시오.

 

 

입력 및 출력

 

더보기

입력

 

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

 

출력

 

첫째 줄에 문제에 주어진 연산을 K번 했을 때, 만들 수 있는 가장 큰 수를 출력한다. 만약 연산을 K번 할 수 없으면 -1을 출력한다.

 

입력 예시

 

16375 1

 

출력 예시

 

76315

 

 


 

풀이

 

기껏 풀고 나니 1년 전 과거의 내가 풀었다는 걸 그제야 알게 된 문제... 심지어 풀이법도 재귀를 쓰느냐 반복문을 이용하냐의 차이뿐이었다.

 

핵심은 1 ~ K번까지 주어진 연산을 수행하는 경우를 완전 탐색해 보는 것. N값의 자릿수는 최대 7이므로, 한 차례에서 두 숫자를 바꾸는 경우의 수는 7*6 = 42가지 경우가 나올 수 있으며 바꾼 수가 0으로 시작하는 경우를 제하면 더 적어진다. 또한 최대 K는 10이므로 경우의 수 자체가 최대 42^10이 되지만, 우리는 숫자의 범위 상 이 경우의 수가 겹치는 경우가 매우 많음을 알 수 있다. 동일 차례에서 한 차례 만들어냈던 숫자는 다시 방문하지 않도록 visited를 작성하여 활용하면 가지치기로 경우의 수가 더 줄어든다. 즉 그래프 탐색 문제로 풀이할 경우 쉽게 풀 수 있겠다.

 

풀이 코드

N, K = input().split()
N = list(N)
M = len(N)
K = int(K)

answer = -1
visited = [[False]*1000001 for i in range(K+1)]
def dfs(idx) :
  global answer
  if idx == K :
    answer = max(answer, int(''.join(N)))
    return
  for i in range(M-1) :
    for j in range(i+1, M) :
      if i == 0 and N[j] == '0' :
        continue
      N[i], N[j] = N[j], N[i]
      num = int(''.join(N))
      if not visited[idx][num] :
        visited[idx][num] = True
        dfs(idx + 1)
      N[i], N[j] = N[j], N[i]

dfs(0)
print(answer)

풀이 완료!

'PS > 백준' 카테고리의 다른 글

[백준/1153] 네 개의 소수 (Python)  (1) 2023.10.17
[백준/10868] 최솟값 (Python)  (1) 2023.10.16
[백준/5214] 환승 (Python)  (1) 2023.10.15
[백준/1033] 칵테일 (Python)  (0) 2023.10.13
[백준/2225] 합분해 (Python)  (0) 2023.10.12
Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.