ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Python 3] BOJ - 1744 "수 묶기"
    BOJ 2020. 9. 16. 17:54

     # 문제 링크 : https://www.acmicpc.net/problem/1744

     

    1744번: 수 묶기

    길이가 N인 수열이 주어졌을 때, 그 수열의 합을 구하려고 한다. 하지만, 그냥 그 수열의 합을 모두 더해서 구하는 것이 아니라, 수열의 두 수를 묶으려고 한다. 어떤 수를 묶으려고 할 때, 위치에

    www.acmicpc.net

     # 풀이 :

     개인적으로 이 문제의 핵심은 0, 1의 처리라고 생각한다. 만일, 0, 1이 쿼리 내에 들어오지 않는다면 음수와 양수의 두 리스트로 나누어 음수는 오름차순으로, 양수는 내림차순으로 정렬 후 짝수개 씩 묶어준 후 곱한다. 이후 쌍으로 묶이지 않는 음수와 양수를 모두 더해주면 된다. 그런데 0, 1이 쿼리 내에 들어오지 않는다는 가정이 없기 때문에, 각각의 경우에 대하여 고려해야 한다.

    <그림 1>

     만일 그림 1처럼 수의 쌍들을 묶게 된다면 얻을 수 있는 값은 7이다. 그러나, 최적해는 어떠한 수도 묶지 않는 것이다. 따라서 최적해는 9이다. 왜냐하면 1은 곱셈을 하는 결과가 자기자신이기 때문에, 1은 항상 곱하는 것이 아니라 더해줘야 한다.

    <그림 2>

     만일 그림 2처럼 수의 쌍을 묶게 된다면 얻을 수 있는 값은 60이다. 그러나, 최적해는 -8과 -7, -1과 0을 묶는 것이다. 왜냐하면 0은 어떤 수와 묶는다 하더라도 0이 되기 때문에 쌍을 이루지 못하는 음수를 묶으면 수들의 합의 최댓값을 구할 수 있다. 따라서 음수를 담고 있는 리스트에서 한 쌍을 뽑고 쌍을 이루지 못하는 음수들이 있고 0이 존재한다면 0과 나머지 음수를 묶는다. 그래도 남는 음수들은 어쩔 수 없이 더해줘야 한다

     이후 짝수도 같은 과정을 거치되, 쌍을 이루지 않는 짝수는 굳이 0과 묶어줄 필요가 없으므로 그대로 더한다. 마지막으로 1은 묶지 않는 것이 이득이므로 1의 갯수만큼 더해주면 정답을 구할 수 있다.

     

    import sys
    
    # 입력부
    n = int(sys.stdin.readline())
    
    # neg : 음수 리스트
    # pos : 1 제외 양수 리스트
    # zero : 0 리스트
    # one : 1 리스트
    neg = []
    pos = []
    zero = []
    one = []
    
    # 각 숫자를 경우에 따라 다른 리스트에 담는다
    for i in range(n):
        n = int(sys.stdin.readline())
        if n < 0:
            neg.append(n)
        elif n > 1:
            pos.append(n)
        elif n == 1:
            one.append(n)
        else:
            zero.append(n)
            
    # 음수는 내림차순 (절댓값이 큰 수가 앞에), 양수는 오름차순으로 정렬한다
    neg.sort(reverse=True)
    pos.sort()
    
    # ans : 정답 배열
    ans = []
    
    # 음수 리스트에서 쌍을 추출후, 정답배열에 곱한 값을 넣는다
    while len(neg) >= 2:
        ans.append(neg.pop() * neg.pop())
        
    # 남은 음수에 대해
    while neg:
    	# 0 리스트가 비지 않았다면 0과 나머지 음수를 묶어준다
        if zero:
            zero.pop()
            neg.pop()
        # 0 리스트가 비었다면 나머지 음수를 정답 배열에 추가한다
        else:
            ans.append(neg.pop())
            
    # 양수 배열도 마찬가지로 한 쌍으로 묶은 값을 정답배열에 저장하고 남은 양수도 정답 배열에
    # 그대로 저장한다
    while len(pos) >= 2:
        ans.append(pos.pop() * pos.pop())
    while pos:
        ans.append(pos.pop())
        
    # 마지막으로 1을 정답 배열에 추가한다
    while pone:
        ans.append(one.pop())
        
    # 정답 출력
    print(sum(ans))

    'BOJ' 카테고리의 다른 글

    [Python 3] BOJ - 14395 "4연산"  (0) 2021.08.02
    [Python 3] BOJ - 9663 "N-Queen"  (2) 2021.07.01
    [Python 3] BOJ - 1722 "순열의 순서"  (0) 2020.09.15
    [Python 3] BOJ - 1707 "이분 그래프"  (0) 2020.07.08
    [Python 3] BOJ - 1701 "Cubeditor"  (2) 2020.07.08

    댓글

Designed by Tistory.