
이제 곧 코테를 보러 여기저기 다니게 된다.
자주 쓸 형태를 까먹지 않게 기록해놓자.
별은 내가 생각하는 중요도로 지극히 주관적이다.
주로 내가 볼거기 때문에 설명보다는 바로 코드만 쓴다.
또한 문제풀며 계속 추가+수정할 계획이다.
def is_prime(n: int) -> bool:
if n<2:
return False
# 짝수 제거
prime_numbers = [True for _ in range(n+1)]
i = 2
while 2*i<=n:
prime_numbers[2*i] = False
i += 1
# 홀수끼리만 소수 판별
for i in range(3, int(n**0.5)+1, 2):
if prime_numbers[i]==True:
j = i
while i*j<=n:
prime_numbers[i*j] = False
j += 2
return prime_numbers[-1]
def is_prime(n: int) -> bool:
if n<2:
return False
elif n<4:
return True
elif n%2==0:
return False
for x in range(5, int(n*0.5)+1, 2):
if n%x==0:
return False
else:
return True
말해 뭐해.. 가장 중요한 빈출 유형.
여기서는 2차원 배열을 탐색하는 코드를 정리한다.
from collections import deque
H, W = map(int, input().split())
visited = [[False]*W for _ in range(H)]
visited[0][0] = True
board = [[0]*W for _ in range(H)]
def bfs():
global H, W, visited
q = deque([(0, 0)])
while q:
row, col = q.popleft()
for new_row, new_col in [(row+1, col), (row-1, col), (row, col+1), (row, col-1)]:
if 0<=new_row<H and 0<=new_col<W and board[new_row][new_col]==0:
visited[new_row][new_col] = True
q.append((new_row, new_col))
from collections import deque
H, W = map(int, input().split())
visited = [[False]*W for _ in range(H)]
visited[0][0] = True
board = [[0]*W for _ in range(H)]
def dfs(row: int, col: int):
global H, W, visited
for new_row, new_col in [(row+1, col), (row-1, col), (row, col+1), (row, col-1)]:
if 0<=new_row<H and 0<=new_col<W and board[new_row][new_col]==0:
visited[new_row][new_col] = True
dfs(new_row, new_col)
def binary_search(lst: list, x: int) -> int:
lp, rp = 1, len(lst)-1
while lp<=rp:
cp = (lp+rp)//2
if lst[cp]==x:
return cp
elif lst[cp]>x:
rp = cp-1
else:
lp = cp+1
return rp
from bisect import bisect_left
idx = bisect_left(lst, x)
별 두개를 줄까 하다가, 2022년 카카오 코테에서
이를 활용하면 쉽게 풀리는 문제가 있어 3개 줬다.
자주 나오는 유형은 아니지만, 까먹으면 치명적이기에 암기 중요도는 높은 편.
# 초기 배치는 73 = 1001001(2)
bit = 73
# 3번째 위치에 할당하기 (이미 할당되었다면 값 변화 x)
# 실행 결과는 77 = 1001101(2)
bit = bit | (1<<2)
# 4번째 위치 제거하기
# 실행 결과는 69 = 1000101(2)
bit = bit & ~(1<<3)
# 7번째 위치 할당여부 확인
# 실행 결과는 True
bit == bit | (1<<6)
단순히 집합 여부를 판단하는 용도라면 별 세개겠지만
크루스칼 알고리즘이나 특정 상황에서 은근 자주 쓰인다.
집합 관련되었다면 일단 믿고쓰는 국밥 기법.
경로 단축 개념을 모른다면 반드시 보고 적용하자.
def find(x: int) -> int:
global parent
if parent[x]!=x:
parent[x] = find(parent[x])
return parent[x]
def union(a: int, b: int):
global parent
pa, pb = find(a), find(b)
if pa!=pb:
parent[min(pa, pb)] = max(pa, pb)
좀 지엽적인 알고리즘일 수 있으나,
선후관계가 조성되어 있는 문제에서는 국밥처럼 든든한 친구.
from collections import deque
N = int(input())
next_nodes = [set() for _ in range(N)]
indegrees = [0]*(N)
for node in range(N):
# next_nodes 리스트에 선후관계를 채워넣는 로직
q = deque()
for node in range(N):
if indegrees[node]==0:
q.append(node)
while q:
node = q.popleft()
for next_node in next_nodes[node]:
indegrees[next_node] -= 1
if indegrees[next_node]==0:
q.append(next_node)
얘가 기업 코테에 활용될 상황이면 그냥 대부분 못풀지 않을까 싶다.
그냥 내가 자꾸 구현방법을 까먹어서 여기 남겨놓는다.
from math import log2, ceil
def segment(idx: int, fr: int, to: int) -> int:
global lst, segment_tree
if fr==to:
segment_tree[idx] = lst[fr]
else:
c = (fr+to)//2
segment_tree[idx] = segment(2*idx, fr, c)+segment(2*idx+1, c+1, to)
return segment_tree[idx]
def edit(idx: int, target: int, change_to: int, fr: int, to: int) -> int:
global segment_tree
if target<fr or target>to:
pass
elif fr==to==target:
segment_tree[idx] = change_to
else:
c = (fr+to)//2
segment_tree[idx] = edit(2*idx, target, change_to, fr, c)+edit(2*idx+1, target, change_to, c+1, to)
return segment_tree[idx]
def get_value(idx: int, target_fr: int, target_to: int, fr: int, to: int) -> int:
global segment_tree
if target_to<fr or target_fr>to:
return 0
elif fr>=target_fr and to<=target_to:
return segment_tree[idx]
else:
c = (fr+to)//2
return get_value(2*idx, target_fr, target_to, fr, c)+get_value(2*idx+1, target_fr, target_to, c+1, to)
N = int(input())
lst = [int(input()) for _ in range(N)]
segment_tree = [0]*(1+2**(ceil(log2(N))+1))
segment(1, 0, N-1)
edit(1, fr, to, 0, N-1)
get_value(1, fr, to, 0, N-1)
.
.
.
계속 추가 예정