백준 1715번 카드 정렬하기 문제

 

 

n = int(input())
data = []
for _ in range(n):
    data.append(int(input()))
data.sort()

if len(data) == 1:
    print(data[0])
    exit()

result = 0
result += data[0] * (len(data) - 1)
for i in range(1, len(data)):
    result += data[i] * (len(data) - i)
print(result)

최초 코드

 

import heapq
n = int(input())
data = list(int(input()) for _ in range(n))
heapq.heapify(data) # heapify를 통해 기존 리스트를 heap으로 변환
result = 0

while len(data) != 1:
    num1 = heapq.heappop(data)
    num2 = heapq.heappop(data)
    result += num1 + num2
    heapq.heappush(data, num1 + num2)
print(result)

최종 코드

 

최종 코드 제출

 

 

최초에는 데이터 값들의 연속성을 발견하여

 

n

n - 1 / n - 1

n - 1 / n - 1 / n - 2

n - 1 / n - 1 / n - 2 / n -3

n - 1 / n - 1 / n - 2 / n - 3 / n - 4 

.....................

 

을 기본항으로 문제를 풀어보려 했으나

 

우리가 구해야하는건 최소의 값

즉 데이터를 정렬해서 제일 작은 두 항을 묶고, 그 항을 다시 리스트의 맨 앞으로 불러들여

또 다시 제일 작은 두 항을 묶어야 하는 문제였다 ( 1개가 남을 때 까지 )

 

원래는 heap을 사용하지 않고, list를 사용하여 풀려 했었다

pop(0)를 사용하여 x = pop(0), y = pop(0), data.append(x+y)

하지만 여러가지 한계에 봉착하게 되었다.

 

내일은 heap과 우선순위 큐에 대해서 다시 한번 공부하는 시간을 가져야겠다.

백준 1339번 단어 수학 문제

 

n = int(input())
num = [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
dict_data = {'A': 0, 'B': 0, 'C': 0, 'D': 0, 'E': 0, 'F': 0, 'G': 0, 'H': 0, 'I': 0, 'J': 0
             , 'K': 0, 'L': 0, 'M': 0, 'N': 0, 'O': 0, 'P': 0, 'Q': 0, 'R': 0, 'S': 0, 'T': 0, 'U': 0
             , 'V': 0, 'W': 0, 'X': 0, 'Y': 0, 'Z': 0}
data = []
for _ in range(n):
    data.append(input())
data = sorted(data, key=lambda x: len(x), reverse=True)

for i in data:
    for j in i:
        if dict_data[j] == 0:
            dict_data[j] = num.pop(0)

result = []
for i in data:
    tmp = ''
    for j in i:
        tmp += str(dict_data[j])
    result.append(int(tmp))
print(sum(result))

최초 코드

 

n = int(input())
num = [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
dict_data = {'A': -1, 'B': -1, 'C': -1, 'D': -1, 'E': -1, 'F': -1, 'G': -1, 'H': -1, 'I': -1, 'J': -1
             , 'K': -1, 'L': -1, 'M': -1, 'N': -1, 'O': -1, 'P': -1, 'Q': -1, 'R': -1, 'S': -1, 'T': -1, 'U': -1
             , 'V': -1, 'W': -1, 'X': -1, 'Y': -1, 'Z': -1, '!': 0}
data = []
for _ in range(n):
    data.append(input())
data = sorted(data, key=lambda x: len(x), reverse=True)

max_len = len(data[0])


for i in range(len(data)):
    if len(data[i]) != max_len:
        tmp = max_len - len(data[i])
        for _ in range(tmp):
            data[i] = '!' + data[i]

for i in range(max_len):
    for j in range(len(data)):
        if data[j][i] != '!':
            if dict_data[data[j][i]] == -1:
                dict_data[data[j][i]] = num.pop(0)

result = 0
for i in range(max_len):
    for j in range(len(data)):
        print(dict_data[data[j][i]] * (10 ** (max_len - i - 1)))
        result += dict_data[data[j][i]] * (10 ** (max_len - i - 1))
print(result)

두번째 코드

 

n = int(input())
result = 0
num = [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
dict_data = {'A': 0, 'B': 0, 'C': 0, 'D': 0, 'E': 0, 'F': 0, 'G': 0, 'H': 0, 'I': 0, 'J': 0
             , 'K': 0, 'L': 0, 'M': 0, 'N': 0, 'O': 0, 'P': 0, 'Q': 0, 'R': 0, 'S': 0, 'T': 0, 'U': 0
             , 'V': 0, 'W': 0, 'X': 0, 'Y': 0, 'Z': 0, '!': 0}
data = []
for _ in range(n):
    data.append(input())
data = sorted(data, key=lambda x: len(x), reverse=True)
max_len = len(data[0])

for i in range(len(data)):
    if len(data[i]) != max_len:
        tmp = max_len - len(data[i])
        for _ in range(tmp):
            data[i] = '!' + data[i]

for i in range(len(data)):
    for j in range(max_len):
        dict_data[data[i][j]] += (10 ** (max_len - j - 1))

dict_data['!'] = 0
weights = []
for i in dict_data.values():
    if i != 0:
        weights.append(i)
weights.sort(reverse= True)

for i in weights:
    result += i * num.pop(0)
print(result)

최종 코드

 

매우 고단했던 문제.. 주어진 문자의 각 자리수를 맞추어

해당 자리수에 맞게 차례로 큰 숫자부터 부여하며 동시에 연산하려 했으나, 

abb

bb

bb

bb

bb

bb

bb

bb

 

등의 input에 에러가 발생된다.

 

따라서 코드를 아예 전환하여 각 알파벳별로 가중치를 두었다(자리의 수에 따라)

그 가중치를 기준으로 큰 숫자부터 부여하여 계산하니 해결되었다.

 

문제를 보고 풀이를 도출할 수 있는 사고력을 길러야 한다는 생각이 들었다.

배움이 모자라니 시야가 좁아진다.

다양한 풀이와 더 나은 코드를 위해서는 더 열심히 노력해야한다.

풀었다는 사실에 안주하지 말자. 더 나은 코드로 다시 한번 풀어 내 것으로 만들자.

 

파이썬 4796번 캠핑 문제

 

기본적인 수학 공식을 사용하면 바로 풀리는 문제였다.

 

l, p, v가 주어졌을 때, (v // p) * l에서 대부분이 정해지고

남은 일자가 l보다 크다 작다에 따라서 상세값이 정해진다.

 

따라서 v - (v // p) * p < l 일 경우 위 값에 더해주면 되고

아닐 경우 l을 더해주면 된다.

 

count = 1
while True:
    l, p, v = map(int, input().split())
    if l == p == v == 0:
        break
    result = (v // p) * l
    if v - (v // p) * p < l:
        result += v - (v // p) * p
    else:
        result += l

    print("Case %d:" %count, result)
    count += 1

파이썬 1946번 신입 사원 문제

 

테스트 케이스가 많다보니 sys로 input = sys.stdin.readline 해주지 않으면 시간 초과가 발생했다.

 

import sys
input = sys.stdin.readline
for _ in range(int(input())):
    n = int(input())
    data = []
    count = 1
    for _ in range(n):
        data.append(list(map(int, input().split())))
    data.sort()

    tmp = data[0][1]

    for i in range(1, n):
        if tmp > data[i][1]:
            count += 1
            tmp = data[i][1]
    print(count)

 

서류와 면접중 한 점수를 기준으로 오름차순 정렬을 한 뒤

 

총 5명의 지원자 일 경우 

서류 점수가 1등인 자의 면접 점수가 4일 경우

면접점수가 4보다 아래인 사람은 자동으로 탈락이다.

이런식으로 반복을 더해나가며 문제를 해결했다.

 

 

 

물론 처음부터 문제를 해결할 수 있었던건 아니였다.

 

for _ in range(int(input())):
    n = int(input())
    data = []
    count = 0
    for _ in range(n):
        data.append(list(map(int, input().split())))
    data.sort()
    data2 = sorted(data, key= lambda x : x[1])

    result = []
    for i in range(data[0][1] + 1, n + 1):
        result.append(i)

    for i in range(data2[0][0] + 1, n + 1):
        result.append(data[i - 1][1])


    print(n - len(set(result)))

원래는 서류 점수 1등의 면접 점수를 기준으로 그보다 낮은 요소들을

list의 del을 이용해서 제거한 뒤, 남은 인원들의 인원수를 len(data)를 통해 정답을 구하려 했으나

len(data)의 변화를 for 문에서는 초기 len(data)의 값으로만 고정이 된다는 점을 착각하여 index out error가 발생하였다.

 

그래서 리스트를 서류 기준 / 면접 기준으로 2개로 나누어 풀어보았지만, 역시 시간초과가 발생하였다.

 

문제를 단순히 보고 직관적으로 해결할 수 있어야 하는데, 자꾸 스스로 어려운 방향으로 나아가는 것 같다.

그래도 솔직히 정형화 된 방법보단, 즉흥적으로 떠오르는 방법으로 딱 풀었을 때 그 손맛이 계속 코드를 두들기게 하는 것 같다.

 

하지만 내 실력이 쌓일 때 까지는 문제를 파악하고 정확한 해결법을 연상시켜 풀이할 수 있는 PS능력을 기르자!

+ Recent posts