[Silver I] 숫자 재배치 - 16943
성능 요약
메모리: 100324 KB, 시간: 360 ms
분류
백트래킹, 브루트포스 알고리즘, 조합론, 수학
제출 일자
2024년 11월 2일 22:22:49
문제 설명
두 정수 A와 B가 있을 때, A에 포함된 숫자의 순서를 섞어서 새로운 수 C를 만들려고 한다. 즉, C는 A의 순열 중 하나가 되어야 한다.
가능한 C 중에서 B보다 작으면서, 가장 큰 값을 구해보자. C는 0으로 시작하면 안 된다.
입력
첫째 줄에 두 정수 A와 B가 주어진다.
출력
B보다 작은 C중에서 가장 큰 값을 출력한다. 그러한 C가 없는 경우에는 -1을 출력한다.
풀이
나의 잘못된 접근 (Greedy 이용)
import sys
A , B = map(str , sys.stdin.readline().split())
a = [int(i) for i in A]
b = [int(i) for i in B]
r = []
next = False
for i in b:
tmp = []
if(next):
i = i * 10
for w in a:
if(i-w >=0):
if(w not in r):
tmp.append(w)
if(tmp !=[]):
r.append(max(tmp))
if(i-max(tmp) != 0):
next = True
if(len(r)< len(A)):
print(-1)
else:
for _ in r:
print(_, end = "")
순열을 이용한 풀이
import sys
from itertools import permutations
# 파일에서 입력 받기
sys.stdin = open("input.txt", "r")
# A와 B를 문자열로 입력받기
A, B = sys.stdin.readline().split()
B = int(B) # B를 정수로 변환하여 비교
# 가능한 모든 순열을 생성
perms = permutations(A)
max_result = -1
for perm in perms:
# 순열을 숫자로 변환
num = int("".join(perm))
# 조건: B보다 작고, 숫자가 0으로 시작하지 않아야 함
if num < B and str(num)[0] != '0':
max_result = max(max_result, num)
# 결과 출력: 가능한 값이 없으면 -1 출력
print(max_result)
백트랙킹을 이용한 풀이
import sys
A, B = sys.stdin.readline().split()
A_digits = sorted(A, reverse=True) # A의 숫자를 내림차순으로 정렬
B = int(B)
visited = [False] * len(A_digits) # 숫자 사용 여부를 체크하기 위한 리스트
max_result = -1
def find_max_number(current_num):
global max_result
# 숫자를 모두 선택했다면, 현재 숫자가 B보다 작은지 확인
if len(current_num) == len(A):
num = int(current_num)
if num < B:
max_result = max(max_result, num)
return
# 자리별로 숫자를 선택하여 가능한 최대값 찾기
for i in range(len(A_digits)):
if not visited[i]:
# 첫 자리에서 0으로 시작하면 안 됨
if current_num == "" and A_digits[i] == '0':
continue
visited[i] = True
find_max_number(current_num + A_digits[i])
visited[i] = False
find_max_number("")
print(max_result)