BAEKJOON #1744 (정렬) - python

nathan·2021년 7월 19일
0

알고리즘문제

목록 보기
20/102

수 묶기

출처 : 백준 #1744

시간 제한메모리 제한
2초128 MB

문제

길이가 N인 수열이 주어졌을 때, 그 수열의 합을 구하려고 한다. 하지만, 그냥 그 수열의 합을 모두 더해서 구하는 것이 아니라, 수열의 두 수를 묶으려고 한다. 어떤 수를 묶으려고 할 때, 위치에 상관없이 묶을 수 있다. 하지만, 같은 위치에 있는 수(자기 자신)를 묶는 것은 불가능하다. 그리고 어떤 수를 묶게 되면, 수열의 합을 구할 때 묶은 수는 서로 곱한 후에 더한다.

예를 들면, 어떤 수열이 {0, 1, 2, 4, 3, 5}일 때, 그냥 이 수열의 합을 구하면 0+1+2+4+3+5 = 15이다. 하지만, 2와 3을 묶고, 4와 5를 묶게 되면, 0+1+(23)+(45) = 27이 되어 최대가 된다.

수열의 모든 수는 단 한번만 묶거나, 아니면 묶지 않아야한다.

수열이 주어졌을 때, 수열의 각 수를 적절히 묶었을 때, 그 합이 최대가 되게 하는 프로그램을 작성하시오.


입력

첫째 줄에 수열의 크기 N이 주어진다. N은 10,000보다 작은 자연수이다. 둘째 줄부터 N개의 줄에, 수열의 각 수가 주어진다. 수열의 수는 -10,000보다 크거나 같고, 10,000보다 작거나 같은 정수이다.


출력

수를 합이 최대가 나오게 묶었을 때 합을 출력한다. 정답은 항상 231보다 작다.


입출력 예시

예제 입력 1

4
-1
2
1
3

예제 출력 1

6


풀이

풀이 설명

  • 이런 문제는 케이스 분류를 잘해야한다.
  • 사실 내가 푼 풀이(1)도 if문이 너무 많아 좋은 풀이는 아니어 보인다.
  • 큐에 넣고 두 원소를 양수, 1, 0, 음수의 경우로 나누어 생각하였다.
  • 풀이 (2)는 리스트에 담아 if문을 최소화하였다.

python code (1)

# 백준 1744번 정렬
from sys import stdin
from collections import deque
def solution(n, arr):
    answer = 0
    queue = deque()
    arr.sort(reverse=True)  # 내림차순 정렬
    plus_count = 0 # 양수 개수 카운트
    zero_count = 0
    minus_count = 0
    for i in range(n):
        if arr[i] > 0:
            plus_count += 1
        elif arr[i] == 0:
            zero_count += 1
        else:
            minus_count += 1
        queue.append(arr[i])

    while queue:
        v = queue.popleft()
        if len(queue) == 0:
            answer += v
        else:
            w = queue.popleft()
            if v > 1 and w > 1:
                answer += v * w
            elif w == 1:
                answer += v + w
            elif v == 1 and w == 0:
                answer += v
                if minus_count % 2 != 0:
                    queue.appendleft(w)
            elif v > 1 and w < 0:
                answer += v
                if minus_count % 2 == 0:
                    queue.appendleft(w)
                else:
                    answer += w
                    minus_count -= 1
            elif v == 0 and w == 0: 
                if minus_count % 2 != 0:
                    queue.appendleft(w)
            elif v == 0 and w < 0:
                if minus_count % 2 == 0:
                    queue.appendleft(w)
                else:
                    minus_count -= 1
            elif v < 0 and w < 0:
                if minus_count % 2 != 0:
                    answer += v
                    queue.appendleft(w)
                    minus_count -= 1
                else:
                    answer += v * w

    return answer

n = int(stdin.readline())
arr = []
for i in range(n):
    arr.append(int(stdin.readline()))

print(solution(n, arr))

python code (2)

# 백준 1744번 정렬
from sys import stdin

def solution(n, arr):
    answer = 0
    arr.sort(reverse=True)  # 내림차순 정렬
    plus = [] 
    one = []
    zero = []
    minus = []
    for x in arr:
        if x > 1:
            plus.append(x)
        elif x == 1:
            one.append(x)
        elif x == 0:
            zero.append(x)
        else:
            minus.append(x)

    if len(plus) % 2 == 0:
        for i in range(0, len(plus), 2):
            answer += plus[i] * plus[i+1]
    else:
        for i in range(0, len(plus)-1, 2):
            answer += plus[i] * plus[i+1]
        answer += plus[-1]

    answer += len(one)

    minus.sort()
    if len(minus) % 2 == 0:
        for i in range(0, len(minus), 2):
            answer += minus[i] * minus[i+1]
    else:
        for i in range(0, len(minus)-1, 2):
            answer += minus[i] * minus[i+1]

        if len(zero) == 0:
            answer += minus[-1]

    return answer



n = int(stdin.readline())
arr = []
for i in range(n):
    arr.append(int(stdin.readline()))

print(solution(n, arr))
profile
나는 날마다 모든 면에서 점점 더 나아지고 있다.

0개의 댓글