본문 바로가기

ALGORITHM/SWEA

[SWEA D2] 1959. 두 개의 숫자열(Python)

문제 링크

https://swexpertacademy.com/main/code/problem/problemDetail.do?contestProbId=AV5PpoFaAS4DFAUq&categoryId=AV5PpoFaAS4DFAUq&categoryType=CODE&problemTitle=1959&orderBy=FIRST_REG_DATETIME&selectCodeLang=ALL&select-1=&pageSize=10&pageIndex=1 

 

SW Expert Academy

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

swexpertacademy.com


제출 코드

- Pass

# 리스트 요소 순서 뒤로 하나씩 미루기
def change_list(a):
    a.insert(0, 0)
    a[0] = a[-1]
    a.pop()
    return a

# 짧은 리스트 뒤에 0 넣어 같은 길이로 만들기
def append_zero(a, b):
    if len(a) > len(b):
        for i in range(len(a) - len(b)):
            b.append(0)
        return a, b
    
    elif len(a) < len(b):
        for i in range(len(b) - len(a)):
            a.append(0)
        return a, b
    
    else:
        return a, b

# 리스트 같은 위치끼리의 곱의 합 구하기(반드시 길이 같게 만들고 수행해야)
def multiply(a, b):
    m_sum = 0
    for i in range(len(a)):
        m_sum = m_sum + a[i] * b[i]
    
    return m_sum

T = int(input())
# 여러개의 테스트 케이스가 주어지므로, 각각을 처리합니다.
for test_case in range(1, T + 1):
    # 입력 받기
    N, M = map(int, input().split())
    A = list(map(int, input().split()))
    B = list(map(int, input().split()))
    # A, B 중 짧은 쪽에 0 추가해서 같은 길이로
    A2, B2 = append_zero(A, B)
    
    # 배열 바꿔가며 곱의 합 리스트에 저장
    # 짧은 쪽을 {abs(N-M)+1}번 바꿔야
    # 일단 짧은 쪽 찾기
    if N >= M:
        short = B2
    else:
        short = A2

    # 곱의 합
    result_sum = []
    for i in range(abs(N-M)+1):
        result_sum.append(multiply(A2, B2))
        change_list(short)

    result = max(result_sum)
    print(f"#{test_case} {result}")

- Fail(1차)

     # 배열 바꿔가며 곱의 합 리스트에 저장
    result_sum = []
    for i in range(len(A2)):
        result_sum.append(multiply(A2, B2))
        change_list(A2)

- Fail(2차)

    # 배열 바꿔가며 곱의 합 리스트에 저장
    result_sum = []
    for i in range(abs(N-M)+1):
        result_sum.append(multiply(A2, B2))
        change_list(A2)

풀이

  • 짧은 쪽에 0을 요소로 추가해서 리스트의 길이를 같게 만들고 난 후 리스트 하나의 순서를 바꿔가면서 같은 위치 요소끼리의 곱의 합을 구하면 될 것으로 생각했다.

  • 1차 Fail 코드대로 하면 짧은 쪽이 더 긴 쪽의 양끝을 벗어나면 안 된다는 조건을 무시하게 된다. 위 그림에서 A = [3, 0, 0, 1, 5] 와 같은 형태로 만들어져 곱이 구해지게 된다.
  • 이를 수정하여 두 리스트 길이의 차에 1을 더한 값만큼 순서를 바꾸면서 곱을 구하도록 코드를 수정했는데, A가 길든 B가 길든 A의 순서를 바꾸도록 한 게 문제가 되어 오답이 나왔다.(2차 Fail 코드)
  • 더 짧은 리스트를 찾아 그 리스트의 순서를 바꾸도록 수정했다.(Pass)

알아둘 것 & 생각해볼 것

# 리스트 요소 순서 뒤로 하나씩 미루기
def change_list(a):
    for i in range(len(a)):
        if i == len(a) - 1:
            a[i] = a[0]
        else:
            a[i] = a[i + 1]
    return a
  • 맨 처음에 작성한 리스트 요소 순서를 바꾸는 함수이다.
  • 일단 else 이하의 내용대로 하면 요소를 뒤로 미루는 게 아니라 앞으로 당기는 게 된다.
  • 한줄씩 순차적으로 적용되어 요소가 바뀌기 때문에 나중에 if 이하의 내용이 적용되어 리스트 맨 끝 요소를 바꿀 때 이미 두 번째 요소로 값이 바뀌어 있던 첫 번째 요소 값이 들어가게 된다.
  • 그래서 리스트 맨 앞에 새로 요소를 추가한 뒤에 그 값을 맨 뒤의 요소 값으로 바꾸고 원래 있던 맨 끝 요소는 제거하는 것으로 함수를 수정했다.
  • 지금 보니 새로운 요소를 추가할 때 굳이 다른 값을 넣을 게 아니라 바로 a.insert(0, a[-1]) 이런 식으로 넣으면 값을 수정하는 단계 없이 바로 끝 요소를 제거하면 되겠다.