이 문제가 스택 유형이라는 것을 알고 있어서 쉽게 풀 수 있을 것 같다는 생각을 했다.
혼자였으면 스택이라는 것도 파악 못 할 뻔 했어서 그걸 아니까 조금 자신감이 생긴 느낌이었다.
/ 제출 1 /
import sys
input = sys.stdin.readline
n = int(input())
towers = list(map(int, input().split()))
result = []
while towers:
current = towers.pop()
remains = len(towers)
while remains > 0:
if towers[remains-1] >= current:
break
remains -= 1
result.append(remains)
while result:
print(result.pop(),end= " ")
: 시간 초과
: 테스트 케이스는 괜찮은데, 탑 개당 퇴대 높이가 100,000,000개(1억 개)에다가 최대 탑의 개수가 500,000(50만)개였다.
: 저렇게 일일히 다 계산하면 백퍼 시간에 걸린다. 아 어떻게 개선하지.. 이 문제가 골드인 이유가 있네.
/ 제출 2 /
import sys
input = sys.stdin.readline
n = int(input())
towers = list(map(int, input().split()))
result = []
while towers:
current = towers.pop()
remains = len(towers)
# 수정부분
if towers and max(towers) < current:
result.append('0')
continue
# .
while remains > 0:
if towers[remains-1] >= current:
break
remains -= 1
result.append(str(remains))
# 수정부분
result.reverse()
print(" ".join(result))
# .
1. 만약 검사할 대상 중에 나보다 큰 애가 없다면 검사할 필요가 없으므로 바로 0을 넣게 했다.
2. 마지막 result를 하나하나 뽑을 게 아니라 뭉텅이로 join하면 내부적으로 더 빨리 돌지 않을까해서 그런 식으로 고쳤다.
=> 그래도 시 간 초 과
안 건드린 while문 부분에서 하나하나 검사하면서 문제가 생기는 것 같다. 역시. 어떻게 수정해야할까 ㅠ
다른 분들 풀이를 보니 내 방향성과 다르다.
나는 뒤에서부터 판별하려고 한 생각을 벗어나지 않았다. 그런데 다른 풀이들은 첫 번째 수부터 차례대로 체크해나가며 자기 앞의 값만 비교한다. 자기 앞의 값들은 그리고 줄여준다. 이걸 스택을 이용해 구현한다.
https://www.acmicpc.net/board/view/70952#comment-117675
글 읽기 - [ python ] 정답코드와 시간초과 코드의 차이점을 알려주세요!!!
댓글을 작성하려면 로그인해야 합니다.
www.acmicpc.net
https://ko.wikipedia.org/wiki/%EB%B6%84%ED%95%A0%EC%83%81%ED%99%98%EB%B6%84%EC%84%9D
분할상환분석 - 위키백과, 우리 모두의 백과사전
위키백과, 우리 모두의 백과사전. 컴퓨터 공학에서, 분할상환분석 (amortized analysis)은 주어진 알고리즘의 시간 복잡도나 프로그램을 수행하는데 소요되는 시간 또는 메모리 같은 자원 사용량을
ko.wikipedia.org
import sys
input = sys.stdin.readline
n = int(input())
towers = list(map(int, input().split()))
stack = [[1, towers[0]]] # 맨 앞 답에 닿는 애들
result = [0]
for i in range(1, n):
while stack:
if stack[-1][1] >= towers[i]:
result.append(stack[-1][0]) # 내 앞의 걔가 내 답
stack.append([i+1, towers[i]]) # 나도 걔에 묶여서 쌓여 일단
break
else: # 만약 내 앞의 애가 내가 닿을 지점이 아니야. 그러면 걔 빼, 그리고 다음 턴에서 그 앞의 애 검사
stack.pop() # 어차피 이 pop되는 애가 닿는 지점은 저장되어 있어서 그냥 버리기만 하면 됨.
if not stack:
# 내 앞에 쭉 뺐는데도 내 답(내가 닿을 애)를 찾지 못했다면
result.append(0)
stack.append([i+1, towers[i]]) #내 값 스택에 넣긴 넣어야지
print(" ".join(map(str, result)))
: 호우.. 어렵당..
: 그러니까 스스로 stack에 들어갈 값을 잘 정의해야한다.
: stack에 왜 넣는지, 이걸 해서 어떤 효과가 나는지 생각해보기.
: 일단 이 문제 같은 경우는 내 앞 애들 중에 가까운 순서대로 체크하고 그 다음애 검사하니까 스택으로 검사대상들을 모아줬다.
: 그리고 결과값은 스택에 넣는 순간에 내 값을 기준으로 저장한다. 빼는 순간이 아니라. 이거 전에 BFS인가할 때도 넣는 순간이냐, 빼는 순간이냐에 따라 값이 바뀌는 경우가 있었다. 항상 시점에 신경 쓰자.
: 그리고 특히 이 문제는 생각의 관점이 중요하다. 내 앞의 대상값이 될 애들을 어떻게 최소화할 지..
: 배움이 많은 문제였다.
'CodingTest > Baekjun Online Judge' 카테고리의 다른 글
[ BOJ / 파이썬 ] 2164 카드 2 (0) | 2022.08.14 |
---|---|
[ BOJ / 파이썬 ] 18258 큐2 (0) | 2022.08.14 |
[ BOJ / 파이썬 ] 1874 스택 수열 (0) | 2022.08.13 |
[ BOJ / 파이썬 ] 10773 제로 (0) | 2022.08.13 |
[ BOJ / 파이썬 ] 1158 요세푸스 문제 (0) | 2022.08.11 |