Skip to content

Commit

Permalink
2024-07-05 20:05:15
Browse files Browse the repository at this point in the history
Affected files:
.obsidian/workspace.json
src/content/blog/boj-10159-저울.md
src/content/blog/boj-2841-외계인의-기타-연주.md
  • Loading branch information
gyunseo committed Jul 5, 2024
1 parent 475baec commit 2ed0c89
Show file tree
Hide file tree
Showing 3 changed files with 106 additions and 7 deletions.
30 changes: 24 additions & 6 deletions .obsidian/workspace.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,24 @@
}
}
]
},
{
"id": "9dc6b127649d0dbd",
"type": "tabs",
"children": [
{
"id": "c75042212be2b48d",
"type": "leaf",
"state": {
"type": "markdown",
"state": {
"file": "src/content/blog/boj-2841-외계인의-기타-연주.md",
"mode": "source",
"source": false
}
}
}
]
}
],
"direction": "vertical"
Expand Down Expand Up @@ -85,7 +103,7 @@
"state": {
"type": "backlink",
"state": {
"file": "src/content/blog/boj-10159-저울.md",
"file": "src/content/blog/boj-2841-외계인의-기타-연주.md",
"collapseAll": false,
"extraContext": false,
"sortOrder": "alphabetical",
Expand All @@ -102,7 +120,7 @@
"state": {
"type": "outgoing-link",
"state": {
"file": "src/content/blog/boj-10159-저울.md",
"file": "src/content/blog/boj-2841-외계인의-기타-연주.md",
"linksCollapsed": false,
"unlinkedCollapsed": true
}
Expand All @@ -125,7 +143,7 @@
"state": {
"type": "outline",
"state": {
"file": "src/content/blog/boj-10159-저울.md"
"file": "src/content/blog/boj-2841-외계인의-기타-연주.md"
}
}
}
Expand All @@ -148,9 +166,10 @@
"table-editor-obsidian:Advanced Tables Toolbar": false
}
},
"active": "4de88d0967b6111b",
"active": "c75042212be2b48d",
"lastOpenFiles": [
"src/content/blog/boj-10159-저울.md",
"src/content/blog/boj-2841-외계인의-기타-연주.md",
"src/content/blog/boj-1926-그림.md",
"src/content/blog/leet-code-letter-combinations-of-a-phone-number.md",
"src/content/blog/leet-code-longest-continuous-subarray-with-absolute-diff-less -than-or-equal-to-Limit.md",
Expand Down Expand Up @@ -194,7 +213,6 @@
"src/content/blog/boj-11728-배열-합치기.md",
"src/content/blog/boj-10819-차이를-최대로.md",
"src/content/blog/boj-2230-수-고르기.md",
"src/content/blog/boj-1912-연속합.md",
"src/content/blog/boj-1699-제곱수의-합.md"
"src/content/blog/boj-1912-연속합.md"
]
}
2 changes: 1 addition & 1 deletion src/content/blog/boj-10159-저울.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ ogImage: ""

## 들어가며

걸린시간: 30분
걸린 시간: 30분

처음에 문제를 읽으면서, 물건 쌍의 비교 결과들만으로 각 물건에 대해 딴 물건들과의 비교 결과를 유추하고, 유추 결과를 알 수 없는 물건들의 개수를 보자 마자, 위상 정렬을 떠올렸습니다.
왜냐면요 옛날에, https://www.acmicpc.net/problem/2252 이 문제를 위상정렬로 풀었던 기억이 났었습니다.
Expand Down
81 changes: 81 additions & 0 deletions src/content/blog/boj-2841-외계인의-기타-연주.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
---
author: Gyunseo Lee
title: "BOJ 백준 2841: 외계인의 기타 연주"
pubDatetime: 2024-07-05T19:41:00+09:00
modDatetime: 2024-07-05T19:41:00+09:00
featured: false
draft: false
tags:
- PS
- Algorithms
- BOJ
- 실랜디
- 골랜디
- Binary-Search
description: bisect_left, bisect_right의 의미를 잘 생각해 보자...!
ogImage: ""
---

## Table of contents

## 들어가며

걸린 시간: 33분

문제 조건을 보면, 쿼리의 개수인 N은 최대 50만이고, 각 쿼리 당 탐색을 해야 하는 리스트의 최대 길이는 30만입니다.
그래서 하나의 쿼리에서의 탐색 시간복잡도를 Order of Log P로 최적화하는 것을 의심했습니다.

## 접근

![](https://res.cloudinary.com/gyunseo-blog/image/upload/f_auto/v1720177279/image_uvpvn7.png)
예시 input들을 직접 손으로 그려 가면서 구현 방법에 대해 접근을 했습니다.

1. `(posI, posJ)`로 입력 받은 쿼리에서, `board[posI][posJ]`에 이미 손가락이 올려져 있는지 확인한다. (코드에서는 이를 cacheHit라고 했습니다.)
2. 만약 cache hit가 되지 않았다면, 손가락을 하나 올려야 되기 때문에, 움직임을 +1 해준다.
3. 그리고 지금 실행하려는 쿼리의 posJ보다 큰 값이 `board[posI]` 리스트에 있는지 확인해서, 있다면 그 원소들을 pop해준다. (손가락을 떼준다.)
4. 떼어낸 손가락 개수만큼 움직임을 플러스해준다.

## 구현

```python
import sys
from bisect import bisect_left, bisect_right
input = sys.stdin.readline

if __name__ == "__main__":
ans = 0
N, P = map(int, input().strip().split())
board = [[] for _ in range(7)]
for _ in range(N):
posI, posJ = map(int, input().strip().split())
# print(f"query nums: {posI}, {posJ}")
updateAns = 0
cacheHit = False
rightInsertPos = bisect_right(board[posI], posJ)
# print(f"right insert pos: {rightInsertPos}")
leftInsertPos = bisect_left(board[posI], posJ)
# print(f"left insert pos: {leftInsertPos}")
numPosJ = rightInsertPos - leftInsertPos
# check cache hit
if numPosJ == 0:
# no cache hit, caching!
updateAns += 1
else:
# cache hit!
cacheHit = True

# check if higher j pos exists
if len(board[posI]) > rightInsertPos:
# pop elements that are bigger than query j pos
while board[posI] and board[posI][-1] > posJ:
board[posI].pop()
updateAns += 1

if not cacheHit:
board[posI].append(posJ)
# print(board[posI])
ans += updateAns
print(ans)
```

여기서 손가락이 올려져 있는지 확인 그리고 posJ보다 큰 값이 있는지 확인 이 두 작업은 당연히 bisect_left, bisect_right 라이브러리를 이용해서 order of Log P 시간 복잡도에 해결이 되게 했습니다.

0 comments on commit 2ed0c89

Please sign in to comment.