coding test

[파이썬] 4881. 배열 최소 합

잔망루피 2021. 1. 20. 21:38

swexpertacademy.com/main/learn/course/lectureProblemViewer.do

 

SW Expert Academy

SW 프로그래밍 역량 강화에 도움이 되는 다양한 학습 컨텐츠를 확인하세요!

swexpertacademy.com

 

※ SW Expert 아카데미의 문제를 무단 복제하는 것을 금지합니다.


NxN 배열에 숫자가 들어있다. 한 줄에서 하나씩 N개의 숫자를 골라 합이 최소가 되도록 하려고 한다. 단, 세로로 같은 줄에서 두 개 이상의 숫자를 고를 수 없다.

조건에 맞게 숫자를 골랐을 때의 최소 합을 출력하는 프로그램을 만드시오.

예를 들어 다음과 같이 배열이 주어진다.
 

2

1

2

5

8

5

7

2

2


이경우 1, 5, 2를 고르면 합이 8로 최소가 된다.

 

[입력]
 

첫 줄에 테스트 케이스 개수 T가 주어진다.  1T50
 

다음 줄부터 테스트 케이스의 첫 줄에 숫자 N이 주어지고, 이후 N개씩 N줄에 걸쳐 10보다 작은 자연수가 주어진다. 3N10

 

[출력]
 

각 줄마다 "#T" (T는 테스트 케이스 번호)를 출력한 뒤, 합계를 출력한다.

입력 출력
3
3
2 1 2
5 8 5
7 2 2
3
9 4 7
8 6 5
5 3 7
5
5 2 1 1 9
3 3 8 3 1
9 2 8 8 6
1 5 7 8 3
5 5 4 6 8
#1 8
#2 14
#3 9

 

🎀 다른사람 풀이

 

def MyCalc(y) :
    global sub_result, result
    
    if result < sub_result :
        return
    
    if y == N :		# lst의 행을 다 돌면
        if sub_result < result :
            result = sub_result
        return
    
    for x in range(N) :
        if not visited[x] :
            visited[x] = True
            sub_result += lst[y][x]
            MyCalc(y+1)
            visited[x]=False
            sub_result -= lst[y][x]
            
TC = int(input())
# 여러개의 테스트 케이스가 주어지므로, 각각을 처리합니다.
for tc in range(1, TC + 1):
    N=int(input())
    lst=[list(map(int, input().split())) for _ in range(N)]
    visited=[0]*N
    sub_result, result=0, 987654321
    MyCalc(0)
    
    print(f"#{tc} {result}")

 

N번 입력받은 값들을 리스트로 lst에 저장한다.

N의 크기만큼 리스트 visited를 초기화한다.

y랑 N이 같고(lst의 행을 다 돌면) sub_result가 result보다 작으면 result에 sub_result를 할당한다. 더 작은 값으로 결과값인 result를 갱신.

sub_result는 시작한 행의 합을 구하는 변수.

N번 반복문을 돌린다.

visited[x]의 값이 False라면 visited[x]를 True로 만든다.

sub_result에 lst[y][x]의 값을 더해간다. MyClac함수를 재귀호출한다. 그 다음 행의 값과 더할려고.

return한 뒤 visited[x]를 False로 만든다. sub_result에서 lst[y][x]를 뺀다. sub_result 초기화.

 

x=2

visited=t,t,f

sub_result=10

 

x=1

visited=t,f,f

sub_result=2

 

x=2

visited=t,f,t

sub_result=7

 

y=2

visited=t,t,t

sub_result=9

 

y=3

y==n이고 sub_result<result이므로 result=9로 return

visited=t,f,t

sub_result=7

 

x=2

visited=t,f,f

sub_result=2

 

x=0

visited=f,f,f

sub_result=0

 

x가 1부터 다시 시작

 

def count(idx, visited, SUM) :
    global MIN
    if idx >= N :
        if SUM < MIN :
            MIN = SUM
        return

    if SUM > MIN :
        return
    for k in range(0, N) :
        if visited[k] == 0 :    # k번째 값에 접근한 적이 없다면
            SUM += maze[idx][k]
            visited[k] = 1
            count(idx+1, visited, SUM)
            visited[k]=0    # 원상복구
            SUM -= maze[idx][k]

T=int(input())
for TC in range(1, T+1) :
    N=int(input())
    maze=list()
    for i in range(N) :
        arr=list(map(int, input().split()))
        maze.append(arr)

    visited={}
    for i in range(0, N) :
        visited[i]=0
    SUM=0
    MIN=99999

    count(0, visited, SUM)

    print("#%d %d" %(TC, MIN))

 

visited를 딕셔너리로 만들었다. visited의 key값은 인덱스고 초기값은 0이다.

count함수를 호출한다. idx가 N보다 크거나 같고(같다라고만 하는게 더 정확함) SUM < MIN이면 MIN에 SUM을 할당.

visited[k]가 0이면 SUM에 maze[idx][k]를 더한다. visited[k]를 1로 만든다.

count함수를 재귀호출한다.

visited[k]를 0으로 만들고 SUM에서 maze[idx][k]를 뺀다. 

알고리즘이 첫번째 코드와 같음.

반응형

'coding test' 카테고리의 다른 글

[파이썬] 5105. 미로의 거리  (0) 2021.01.25
[파이썬] 5097.회전  (0) 2021.01.25
[파이썬] 4880. 토너먼트 카드게임  (0) 2021.01.18
[파이썬] 4875. 미로  (0) 2021.01.15
[파이썬] 4874. Forth  (0) 2021.01.14