알고리즘/알고리즘_swea

[Python][SWEA] 1244. [S/W 문제해결 응용] 2일차 - 최대 상금

Jerry_K 2024. 5. 18. 15:45

🗒️ 파이썬 코드 풀이

def dfs(n) :
    global ans
    if n >= N :
        ans = max(ans,int("".join(s_lst)))
        return

    for i in range(length-1):
        for j in range(i+1,length):
            s_lst[i],s_lst[j] = s_lst[j],s_lst[i]
            chk = int("".join(s_lst))
            if (n,chk) not in v :
                v.append((n,chk))
                dfs(n+1)
            s_lst[i], s_lst[j] = s_lst[j], s_lst[i]

T = int(input())
for tc in range(1,T+1):
    lst,N = map(int,input().split())
    s_lst = list(str(lst))
    length = len(s_lst)
    ans = n = 0
    v = []
    dfs(n)

    print(f"#{tc} {ans}")

 

1. dfs로 완전탐색으로 문제를 해결한다.

 

2. 숫자의 위치를 자유롭게 바꿔야하기 때문에 str형태로 바꿔준다.

 

3.

dfs 함수 :

- 재귀함수의 탈출을 위한 if문을 먼저 만들어준다. 

해당 조건에 만족했을 때의 s_lst의 max 값을 갱신하고 return을 해준다.

(여기서 주의해야 할 것은 내가 원하는 것은 n번째의 최대값이다. 따라서 n==N일때의 최대값을 구해야지 n < N 일때의 최대값은 의미가 없다.  그래서 최대값 갱신은 n == N 일때 하는 것이다.)

 

- 2중 for문 (조합)을 해주고 s_lst[i]와 s_lst[j]의 값을 바꿔준다.

값이 교환된 조합과 n의 값이 v에 없으면 , v에 변경된 값과 n을 넣어주고 dfs를 호출한다.

그리고 다시 변경한 값을 되돌려 놓는다.

 

 

 

🧐 문제 코멘트

문제가 어렵다... 일반 재귀함수를 푸는 문제보다 더 복잡하다.

특히 2중 for문을 이용해서  재귀함수를 구하는 과정이 너무 어려웠다 ㅠㅠ


📚 문제

퀴즈 대회에 참가해서 우승을 하게 되면 보너스 상금을 획득할 수 있는 기회를 부여받는다.

우승자는 주어진 숫자판들 중에 두 개를 선택에서 정해진 횟수만큼 서로의 자리를 위치를 교환할 수 있다.

예를 들어, 다음 그림과 3, 2, 8, 8, 8 의 5개의 숫자판들이 주어지고 교환 횟수는 2회라고 하자.

교환전>



처음에는 첫번째 숫자판의 3과 
네 번째 숫자판의 8을 교환해서 8, 2, 8, 3, 8이 되었다.
 



다음으로, 두 번째 숫자판 2와 마지막에 있는 8을 교환해서 8, 8, 8, 3, 2이 되었다.



정해진 횟수만큼 교환이 끝나면 숫자판의 위치에 부여된 가중치에 의해 상금이 계산된다.

숫자판의 오른쪽 끝에서부터 1원이고 왼쪽으로 한자리씩 갈수록 10의 배수만큼 커진다.

위의 예에서와 같이 최종적으로 숫자판들이 8,8,8,3,2의 순서가 되면 88832원의 보너스 상금을 획득한다.

여기서 주의할 것은 반드시 횟수만큼 교환이 이루어져야 하고 동일한 위치의 교환이 중복되어도 된다.

다음과 같은 경우 1회의 교환 횟수가 주어졌을 때 반드시 1회 교환을 수행하므로 결과값은 49가 된다.



94의 경우 2회 교환하게 되면 원래의 94가 된다.

정해진 횟수만큼 숫자판을 교환했을 때 받을 수 있는 가장 큰 금액을 계산해보자.

[입력]

가장 첫 줄은 전체 테스트 케이스의 수이다.

최대 10개의 테스트 케이스가 표준 입력을 통하여 주어진다.

각 테스트 케이스에는 숫자판의 정보와 교환 횟수가 주어진다.

숫자판의 정보는 정수형 숫자로 주어지고 최대 자릿수는 6자리이며, 최대 교환 횟수는 10번이다.

[출력]

각 테스트 케이스마다, 첫 줄에는 “#C”를 출력해야 하는데 C는 케이스 번호이다.

같은 줄에 빈 칸을 하나 사이에 두고 교환 후 받을 수 있는 가장 큰 금액을 출력한다.