[PY] <!> 하자있는 채로 풀었던 내용들

내가 직접 손 쓴 것이 거의 없는데 과연 블로그에 글을 쓰는게 맞을까라는 생각이 들었던 이번 주였다.
그래서 시간이 남는다면 (부디 그렇다면 좋겠다) 다시 눈여겨 봐야 할 문제들에 대해 정리 해두려고 한다.

edited_just-work-하라고~.png

우선순위 큐를 사용해서 해낼 수 있는 문제(들) :

1655 : 가운데를 말해요

https://www.acmicpc.net/problem/1655

우선순위 큐는 최대 힙 또는 최소 힙을 사용해서 만들어지는데, 꼭 큐의 형태를 생각하지 않더라도 항상 첫번째 원소가 최대 또는 최소를 가리키는 배열 두 개를 갖고 중앙값을 찾아야 하는 문제라고 생각하면 보다 직관적으로 생각 할 수 있었다.

하지만.. 이 아이디어에서 더 진도를 나가지 못했다. 뭔가 더 많이 떠올려야 하는데 이어가지질 않았다.
뒤에 일정이 예정 되어 있는게 많았기에 많은 시간을 들일 수 없었다. 

더보기
import heapq, sys

n = int(sys.stdin.readline())

leftHeap = []
rightHeap = []

for i in range(n):
    num = int(sys.stdin.readline())

    if len(leftHeap) == len(rightHeap):
        heapq.heappush(leftHeap, -num)
    else:
        heapq.heappush(rightHeap, num)


    if rightHeap and rightHeap[0] < -leftHeap[0]:
        leftVal = heapq.heappop(leftHeap)
        rightVal = heapq.heappop(rightHeap)

        heapq.heappush(leftHeap, -rightVal)
        heapq.heappush(rightHeap, -leftVal)

    print(-leftHeap[0])

1715 : 카드 정렬하기

https://www.acmicpc.net/problem/1715

의미있는 아이디어를 도출 하지 못했다. 근데 정답 처리 코드는 무척 쉽게 구성되어있던 걸 보면 조금 생각하면 어떻게 됐겠다 생각은 든다.

더보기
import sys, heapq

n = int(sys.stdin.readline())

cards = []
count = 0

for _ in range(n):
    heapq.heappush(cards, int(sys.stdin.readline()))

while len(cards) != 1:
    temp = heapq.heappop(cards) + heapq.heappop(cards)
    count += temp
    heapq.heappush(cards, temp)

print(count)

13334 : 철로

https://www.acmicpc.net/problem/13334

앞의 케이스처럼 의미있는 아이디어를 도출하지 못했다.

더보기
import sys
import heapq

# 입력값 받기
n = int(sys.stdin.readline().strip())
locations = [] # ([(시작 좌표, 끝 좌표) ...]
for _ in range(n):
    h, o = map(int, sys.stdin.readline().strip().split())
    # 집과 사무실 중 좌표값이 낮은 것을 앞에, 좌표값이 높은 것을 뒤에 넣어줌
    locations.append((min(h, o), max(h, o)))
d = int(sys.stdin.readline().strip())

# 선분의 끝점을 기준으로 오름차순 정렬한 다음, 앞점을 기준으로 오름차순 정렬
locations.sort(key=lambda x: (x[1], x[0]))

heap = []
max_cnt = 0

for location in locations: # 각 사람의 좌표를 기준으로 반복문 돌기
    start, end = location
    heapq.heappush(heap, start) # 최소 힙. pop했을 때 start가 작은 것부터 나올 수 있도록
    line_start = end - d # 현재 사람의 끝 좌표를 기준으로 철로의 시작 지점 계산
    while heap and heap[0] < line_start: # heap[0] = 힙에 저장된 시작 지점 중 최소값
        heapq.heappop(heap) # 철로의 시작 지점보다 시작 좌표가 작은 경우 철로를 벗어나므로 pop
    max_cnt = max(max_cnt, len(heap)) # 현재 철로에 포함되는 사람 수가 최대값인 경우 갱신

print(max_cnt)

분할정복을 사용해서 해낼 수 있는 문제(들) :

2261 : 가장 가까운 두 점

이 문제를 풀기 전에 히스토그램에서의 최대 직사각형 문제를 풀었었는데 이 곳에도 적용 할 수 있을까를 고민했다. 아쉽게도 더 이어 갈 순 없었다. 적어 내려오면서 생각해 본건데, 구체화하는데 뭔가 좀 정성을 더 들여야 할 듯.

더보기
import sys

n = int(sys.stdin.readline())

points = []

for _ in range(n):
    x, y = map(int, input().split())
    points.append((x, y))

points.sort()

def computeMinDist(start, end):
    min_dist = int(1e10)
    for i in range(start, end - 1):
        for j in range(i + 1, end):
            dist = (points[i][0] - points[j][0])**2 + (points[i][1] - points[j][1])**2
            min_dist = min(min_dist, dist)
    return min_dist

def findMinDist(start, end):
    size = end - start
    if size < 3:
        return computeMinDist(start, end)
    
    mid = (start + end) // 2

    left = findMinDist(start, mid)
    right = findMinDist(mid, end)

    min_dist = min(left, right)

    check_point = []
    divide_x = points[mid][0]

    for i in range(start, end):
        if (points[i][0] - divide_x)**2 <= min_dist:
            check_point.append(points[i])
    check_point.sort(key=lambda x:x[1])

    for i in range(len(check_point)):
        now = check_point[i]
        for j in range(i + 1, len(check_point)):
            compare = check_point[j]
            if(compare[1] - now[1])**2 >= min_dist:
                break
            dist = (now[0] - compare[0])**2 + (now[1] - compare[1])**2
            min_dist = min(min_dist, dist)
    return min_dist

print(findMinDist(0, n))

# https://codable.tistory.com/4

스택을 사용해서 해낼 수 있는 문제(들)

10000 : 원 영역

https://www.acmicpc.net/problem/10000

대체 이걸 스택으로 할 수 있다고 어떻게 상상하지? 난 이 시점에서 이 문제에 대한 내용을 놔버렸다.

더보기
import sys
n = int(sys.stdin.readline())

circles = []
for _ in range(n):
    x, r = map(int, sys.stdin.readline().split())
    circles.append(("L", x - r))
    circles.append(("R", x + r))

circles.sort(key=lambda x: (x[0]), reverse=True)
circles.sort(key=lambda x: x[1])

stack = []
count = 1

for circle in circles:
    if circle[0] == "L":
        stack.append(circle)
        continue


    total_width = 0
    while stack:
        prev = stack.pop()

        if prev[0] == "L":

            width = circle[1] - prev[1]

            if total_width == width:
                count += 2
            else:
                count += 1

            stack.append(("C", width))
            break
        elif prev[0] == "C":
            total_width += prev[1]
print(count)

# https://e-juhee.tistory.com/entry/python-%EB%B0%B1%EC%A4%80-10000-%EC%9B%90-%EC%98%81%EC%97%AD-%EC%8A%A4%ED%83%9D

2504 : 괄호의 값

https://www.acmicpc.net/problem/2504

여기 문제 중에서 할만한 문제 중 하나였다. 나중가니 더 요상한 내용을 요구해서 하다가 말았지만..

더보기
import sys

arr = sys.stdin.readline()
stack = []

answer = 0
tmp = 1

for i in range(len(arr)):
    if arr[i] == '(':
        stack.append(arr[i])
        tmp *= 2
    elif arr[i] == '[':
        stack.append(arr[i])
        tmp *= 3
    elif arr[i] == ")":
        if not stack or stack[-1] == "[":
            answer = 0
            break
        if arr[i - 1] == "(":
            anwser += tmp
        stack.pop()
        tmp //= 2
    else:
        if not stack or stack[-1] == "(":
            answer = 0
            break
        if arr[i - 1] == '[':
            answer += tmp
        stack.pop()
        tmp //= 3

if stack:
    print(0)
else:
    print(answer)


# https://velog.io/@rhdmstj17/%EB%B0%B1%EC%A4%80-2504%EB%B2%88-%EA%B4%84%ED%98%B8%EC%9D%98-%EA%B0%92-python-stack-%EC%9E%90%EC%84%B8%ED%95%9C-%ED%92%80%EC%9D%B4

2812 : 크게 만들기

얘는 시도중이다.

'문제풀이' 카테고리의 다른 글

[PY] 1260 : DFS와 BFS  (0) 2025.03.28
[PY] 시작부터 막힌 그래프 [1991 : 트리 순회]  (0) 2025.03.28
[PY]<!> 9935 : 문자열 폭발  (0) 2025.03.27
[PY] 10815 : 숫자카드  (0) 2025.03.27
[PY] 1966 : 프린터 큐  (0) 2025.03.27