SELECT A.cart_id FROM (SELECT cart_id FROM CART_PRODUCTS WHERE NAME='우유') as A, (SELECT cart_id FROM CART_PRODUCTS WHERE NAME='요거트') as B WHERE A.cart_id = B.cart_id
풀이 2: WHERE절에 그냥 NAME을 단순2개 비교하는 조건은 없기때문에, 서브쿼리로 id하나 구해준뒤 AND사용 SELECT cart_id FROM CART_PRODUCTS WHERE cart_id in (SELECT cart_id FROM CART_PRODUCTS WHERE name='우유') AND NAME='요거트' ORDER BY cart_id asc;
풀이 3: SELF JOIN SELECTC.cart_id FROM CART_PRODUCTS C, CART_PRODUCTS T WHERE C.cart_id = T.cart_id AND (C.name='우유' AND T.name='요거트') ORDER BYC.cart_id
n, m = map(int, input().split())
parent = [0]*(n+1)
for i inrange(1, n+1):
parent[i] = i
# 최상위 부모를 찾습니다defgetParent(parent, x):if parent[x] == x:
return x
return getParent(parent, parent[x])
# 최상위 부모끼리 비교해서, 더 작은 값으로 바꿉니다. defunionParent(parent, x, y):
x = getParent(parent, x)
y = getParent(parent, y)
# 둘중, 더 작은 부모를 갖습니다. if x < y:
parent[y] = x
else:
parent[x] = y
for _ inrange(m):
a, b = map(int, input().split())
unionParent(parent, a, b) # 노드끼리 연결합니다.
result = [] # 최상위 부모노드들만 담을 배열for a in parent: # parent의 각 원소마다 최상위 부모노드를 구합니다.
result.append(getParent(parent, a))
#print(result)
result = result[1:] # 0번째 노드는 필요없으니 잘라줍니다.print(len(set(result)))
# 예외처리가 중요# 예외1)) 다 물들였는데, 0 남아있는 경우 : -1 출력# 예외2)) 애초에 0원소가 없는경우 : 0 출력 from collections import deque
m,n = map(int, input().split()) # m: 가로, n: 세로
myMap = []
ripe = deque() # 익은 토마토 위치 for i inrange(n):
row = list(map(int, input().split()))
for j inrange(m):
if row[j] == 1:
ripe.append([i,j])
myMap.append(row)
#print(myMap)#print(ripe) # deque([[0, 0], [3, 5]])
dx = [1,-1,0,0]
dy = [0,0,1,-1]
#visited = [[0]*m for _ in range(n)] # 필요 XdefisInGraph(r, l):# r: 세로, l: 가로if r < 0or r >= n or l < 0or l >= m:
returnFalsereturnTruedefbfs():
days = -1while ripe:
days += 1for _ inrange(len(ripe)): # 현재 ripe의 원소 개수만큼만 반복 !! ★
x, y = ripe.popleft() # [0,0], [3,5] 까지만
tx = 0
ty = 0for i inrange(4):
tx = x + dx[i]
ty = y + dy[i]
if isInGraph(tx, ty):
if myMap[tx][ty] == 0: # [tx, ty] not in ripe 조건 추가하면 시간초과
myMap[tx][ty] = 1
ripe.append([tx,ty])
# 예외1)) for row in myMap:
if0in row:
return -1return days
print( bfs() )
#print(myMap)#참조: https://dojinkimm.github.io/problem_solving/2019/11/03/boj-7576-tomato.html
※ python3로 채점해야 메모리초과 X
※ 방문한 myMap의 원소를 0 -> 1로 바꿔주므로, visited를 통한 방문처리 필요 X
import sys
sys.setrecursionlimit(10**8) # 10^8 까지 늘림.
T = int(input())
for _ inrange(T):
m, n, k = map(int, input().split())
myMap = [[0]*m for _ inrange(n)]
for _ inrange(k):
a, b = map(int, input().split())
myMap[b][a] = 1#print(myMap)
visited = [[0]*m for _ inrange(n)]
dx = [1,-1,0,0]
dy = [0,0,1,-1]
defisInGraph(r, l):# r: 세로, l: 가로if r < 0or r >= n or l < 0or l >= m:
returnFalsereturnTruedefbfs(r, l):
visited[r][l] = 1
tx = 0
ty = 0for i inrange(4):
tx = r + dx[i]
ty = l + dy[i]
if isInGraph(tx, ty):
if visited[tx][ty] == 0and myMap[tx][ty] == myMap[r][l]:
bfs(tx, ty)
ans = 0for i inrange(n): # 세로길이for j inrange(m): # 가로길이 if visited[i][j] == 0and myMap[i][j] != 0:
bfs(i, j)
ans += 1print(ans)
# pypy로 제출하면 메모리초과. python3로 제출해야됨
n = int(input())
m = []
for _ inrange(n):
num = str(input())
num = list(map(int, num))
m.append(num)
#print(m)
visited = [[0]*n for i inrange(n)]
dx = [1,-1,0,0]
dy = [0,0,1,-1]
defisInGraph(r, l):if r < 0or r >= n or l < 0or l >= n:
returnFalsereturnTruedefbfs(r, l):
visited[r][l] = 1
cnt = 1
tx = 0
ty = 0for i inrange(4):
tx = r + dx[i]
ty = l + dy[i]
if isInGraph(tx, ty):
if visited[tx][ty] == 0and m[tx][ty] == m[r][l]:
cnt += bfs(tx, ty)
return cnt
ans = []
for i inrange(n):
for j inrange(n):
if visited[i][j] == 0and m[i][j] != 0:
ans.append(bfs(i, j))
ans.sort()
print(len(ans))
for a in ans:
print(a)
from collections import deque
n = int(input())
m = int(input())
s = [[0]*(n+1) for i inrange(n+1)]
visited = [0]*(n+1)
for _ inrange(m):
a, b = map(int, input().split())
s[a][b] = 1
s[b][a] = 1defbfs(v):
dq = deque([v])
visited[v] = 1
c = 0while(dq):
v = dq.popleft()
for i inrange(1, n+1):
if visited[i] == 0and s[v][i] == 1:
dq.append(i)
visited[i] = 1
c += 1print(c)
bfs(1)
n, m = map(int, input().split())
defgetParent(parent, x):if parent[x] == x: return x
return getParent(parent, parent[x])
defunionParent(parent, x, y):
x = getParent(parent, x)
y = getParent(parent, y)
if x < y:
parent[y] = x
else:
parent[x] = y
parent = [0]*(n+1)
for i inrange(1,n+1):
parent[i] = i
for _ inrange(m):
a, b, c = map(int, input().split())
if a == 0:
unionParent(parent, b, c)
else:
b = getParent(parent, b)
c = getParent(parent, c)
if b == c: print('YES')
else: print('NO')
insert함수를 이용해 단어들을 삽입한뒤, 단어들의 알파벳끼리 연결해서 트리형태로 만든다.
1) 단어가 트리내에 존재하는지 확인해보거나(search함수)
2) 주어진 단어를 prefix로 가지는 단어의 배열을 리턴해준다(starts_with함수)
3) 시간복잡도는 O(m)이다.
classNode:def__init__(self, key,data=None):
self.key = key # 단어의 글자 하나를 담는곳
self.data = data # 사실상 마지막 글자인지 나타내주는 flag# 마지막 글자의 경우에 단어 전체를 data필드에 저장하고,# 아닌 경우는 null로 둔다.
self.children = {} # dict# 즉, Jack의 경우 J, a, c, k 에서 마지막 글자인 K노드의 data필드에만# "Jack"이 들어가고, 그 외 노드의 data필드는 널(None)이다# trie구조를 예쁘게 출력해주는 함수 (http://cd4761.blogspot.com/2017/02/trie-1.html)def__str__(self, depth=0):
s = []
for key in self.children:
s.append('{}{} {}'.format(' ' * depth, key or'#', '\n'
+ self.children[key].__str__(depth + 1)))
return''.join(s)
classTrie:def__init__(self):
self.root = Node('') # key=Nonedef__str__(self, depth=0):return self.root.__str__()
# 트라이에 문자열을 삽입definsert(self, inputString):# print, python, pytorch
curr_node = self.root # 루트부터 시작 for c in inputString: # p, y, t, h, o, nif c notin curr_node.children: # 알파벳이 자식에 존재하지 않으면
curr_node.children[c] = Node(c)
curr_node = curr_node.children[c] # curr_node를 업데이트 # inputString의 마지막 글자 차례이면,# 노드의 data필드에 inputString문자열 전체를 저장한다.
curr_node.data = inputString
# inputString이 트라이에 존재하는지 여부 반환defsearch(self, inputString):
curr_node = self.root # 루트부터 시작for c in inputString:
if c in curr_node.children: # 알파벳이 자식에 존재하면
curr_node = curr_node.children[c] # curr_node를 업데이트else:
returnFalse# 없으면 즉시 False반환 # inputString의 마지막 글자에 도달했을때,# curr_node에 data가 있다면 inputString이 트라이 안에 존재하는것!if curr_node.data != None:
returnTrue# 주어진 prefix로 시작하는 단어들을,# BFS로 트라이에서 찾아 리스트 형태로 반환defstarts_with(self, prefix):# pr
curr_node = self.root # 루트부터 시작
result = []
subtrie = None# 트라이에서 prefix를 찾고,# prefix의 마지막 글자 노드를 subtrie로 설정for c in prefix: # prefix 알파벳 한글자씩 비교 ( p , r )if c in curr_node.children: # 알파벳이 자식에 존재하면
curr_node = curr_node.children[c] # curr_node를 업데이트
subtrie = curr_node # subtrie로 설정print(prefix, '의 알파벳: [',c,']일때 <subtrie>')
print(subtrie)
else:
returnNone# 없으면 즉시 함수 종료# BFS로 prefix subtrie를 순회하며# data가 있는 노드들(=완전한 단어)를 찾는다.# 여기 이해 X
queue = list(subtrie.children.values()) # queue = [Node(i)]print('초기 큐 길이=', len(queue))
while queue:
curr = queue.pop()
print('ㅡㅡㅡㅡㅡㅡㅡ')
print('큐에서 꺼낸 <curr>')
print(curr)
if curr.data != None: # curr.data는 마지막노드에만 존재한다.(완전한 단어형태로 저장되어있다)
result.append(curr.data) # curr.data = 완전한 단어print()
print('>>>result=', result)
print()
queue += list(curr.children.values()) # queue = [Node(n)]return result
# 테스트 코드
trie = Trie()
trie.insert('print')
trie.insert('python')
trie.insert('pytorch')
print('ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ')
if trie.search('python'):
print('python단어 존재!')
if trie.search('java'):
print('java단어 존재!')
print('ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ')
print('<전체 trie구조>')
print(trie)
print('ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ')
trie.starts_with('pr') # ['print']print('ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ')
trie.starts_with('pyt') # ['pytorch', 'python']# 출처 : https://blog.ilkyu.kr/entry/%ED%8C%8C%EC%9D%B4%EC%8D%AC%EC%97%90%EC%84%9C-Trie-%ED%8A%B8%EB%9D%BC%EC%9D%B4-%EA%B5%AC%ED%98%84%ED%95%98%EA%B8%B0
▶ 5052 전화번호 목록 풀이
classNode:def__init__(self, key,data=None):
self.key = key # 단어의 글자 하나를 담는곳
self.data = data # 사실상 마지막 글자인지 나타내주는 flag# 마지막 글자의 경우에 단어 전체를 data필드에 저장하고,# 아닌 경우는 null로 둔다.
self.children = {} # dict# 즉, Jack의 경우 J, a, c, k 에서 마지막 글자인 K노드의 data필드에만# "Jack"이 들어가고, 그 외 노드의 data필드는 널(None)이다# trie구조를 예쁘게 출력해주는 함수 (http://cd4761.blogspot.com/2017/02/trie-1.html)def__str__(self, depth=0):
s = []
for key in self.children:
s.append('{}{} {}'.format(' ' * depth, key or'#', '\n'
+ self.children[key].__str__(depth + 1)))
return''.join(s)
classTrie:def__init__(self):
self.root = Node('') # key=Nonedef__str__(self, depth=0):return self.root.__str__()
# 트라이에 문자열을 삽입definsert(self, inputString):# print, python, pytorch
curr_node = self.root # 루트부터 시작 for c in inputString: # p, y, t, h, o, nif c notin curr_node.children: # 알파벳이 자식에 존재하지 않으면
curr_node.children[c] = Node(c)
curr_node = curr_node.children[c] # curr_node를 업데이트 # inputString의 마지막 글자 차례이면,# 노드의 data필드에 inputString문자열 전체를 저장한다.
curr_node.data = inputString
# inputString이 트라이에 존재하는지 여부 반환defsearch(self, inputString):
curr_node = self.root # 루트부터 시작for c in inputString:
if c in curr_node.children: # 알파벳이 자식에 존재하면
curr_node = curr_node.children[c] # curr_node를 업데이트else:
returnFalse# 없으면 즉시 False반환 # inputString의 마지막 글자에 도달했을때,# curr_node에 data가 있다면 inputString이 트라이 안에 존재하는것!if curr_node.data != None:
returnTrue# 주어진 prefix로 시작하는 단어들을,# BFS로 트라이에서 찾아 리스트 형태로 반환defstarts_with(self, prefix):# pr
curr_node = self.root # 루트부터 시작
result = []
subtrie = None# 트라이에서 prefix를 찾고,# prefix의 마지막 글자 노드를 subtrie로 설정for c in prefix: # prefix 알파벳 한글자씩 비교 ( p , r )if c in curr_node.children: # 알파벳이 자식에 존재하면
curr_node = curr_node.children[c] # curr_node를 업데이트
subtrie = curr_node # subtrie로 설정#print(prefix, '의 알파벳: [',c,']일때 <subtrie>')#print(subtrie)else:
returnNone# 없으면 즉시 함수 종료# BFS로 prefix subtrie를 순회하며# data가 있는 노드들(=완전한 단어)를 찾는다.# 여기 이해 X
queue = list(subtrie.children.values()) # queue = [Node(i)]#print('초기 큐 길이=', len(queue))while queue:
curr = queue.pop()
#print('ㅡㅡㅡㅡㅡㅡㅡ')#print('큐에서 꺼낸 <curr>')#print(curr)if curr.data != None: # curr.data는 마지막노드에만 존재한다.(완전한 단어형태로 저장되어있다)
result.append(curr.data) # curr.data = 완전한 단어#print()#print('>>>result=', result)#print()
queue += list(curr.children.values()) # queue = [Node(n)]return result
T = int(input())
for _ inrange(T):
trie = Trie() # Trie class 초기화
n = int(input())
lst = []
for _ inrange(n):
word = str(input())
lst.append(word)
trie.insert(word)
#print(lst)#print(trie)
flag = 0for a in lst:
t = trie.starts_with(a)
#print(t)iflen(t)>0:
flag = 1breakif flag == 1:
print('NO')
else:
print('YES')
한번 찾은 값을 다시찾지 않기위해서, 10,000,001 과 같이 큰 숫자로 바꿔버리면, arr의 정렬된 형태가 깨져버린다.
ex) [-10, -10, 2, 3, 3, 6, 7, 10, 10, 10] 의 경우, '3'에 대한 이분탐색을 하면 두번째 위치한 3이 먼저 출력된다.
다음 3은 현재 index의 왼쪽에 있다.
ex) [-1, -1, -1, 3, 3] 의 경우'3'에 대한 이분탐색을 하면 첫번째 위치한 3이 먼저 출력된다.
다음 3은 현재 index의 오른쪽에 있다.
▶ 시행착오 2
한번 찾은 값을 다시 찾지 않기 위해서, 따로 표시하는 방법은 어떨까.
그러나 이러한 과정을 거치면 시간초과
표시한다해도, 그다음 이분탐색으로 넘어갈때 같은 값이 왼쪽에 있는지 오른쪽에 있는지 모른다.
▶ 풀이방법 1 : 배열 count 함수 + 딕셔너리 사용 → 시간초과 (오답)
N = int(input())
lst = sorted(list(map(int, input().split()))) # 정렬
M = int(input())
card = list(map(int, input().split()))
dic = {}
for c in card:
dic[c] = lst.count(c)
print(' '.join(str(dic[c]) for c in card))
▶ 풀이방법 2: 이분 탐색 할때 해당 값 찾은후, 배열에서 count + 딕셔너리 사용
N = int(input())
lst = sorted(list(map(int, input().split()))) # 정렬
M = int(input())
card = list(map(int, input().split()))
defBinarySearch(lst, n, low, high):if low > high: # 이분탐색 조건 return -1
mid = (low + high) // 2if n < lst[mid]:
return BinarySearch(lst, n, low, mid-1)
elif n > lst[mid]:
return BinarySearch(lst, n, mid+1, high)
else:
return lst[low:high+1].count(n)
dic = {}
for n in lst:
low = 0
high = len(lst)-1if n notin dic:
dic[n] = BinarySearch(lst, n, low, high)
#print(dic)print(' '.join(str(dic[c]) if c in dic else'0'for c in card))
▶ 풀이방법 3 : arr은 정렬되어있으므로, 이분 탐색으로 해당 값을 찾고, 양 옆에 같은 수 몇개 있는지 세기
+ 딕셔너리 사용
N = int(input())
lst = sorted(list(map(int, input().split()))) # 정렬
M = int(input())
card = list(map(int, input().split()))
defBinarySearch(arr, val, low, high):if low > high:
return0
mid = (low + high) // 2if val < arr[mid]:
return BinarySearch(arr, val, low, mid-1)
elif val > arr[mid]:
return BinarySearch(arr, val, mid+1, high)
else:
i = 1
j = 1
c = 1while mid - i >= 0:
if arr[mid] != arr[mid-i]:
breakelse:
c += 1
i += 1while mid + j < len(arr):
if arr[mid] != arr[mid+j]:
breakelse:
c += 1
j += 1return c
dic = {}
for n in lst:
if n notin dic:
dic[n] = BinarySearch(lst, n, 0, len(lst)-1)
#print(dic) print(' '.join(str(dic[c]) if c in dic else'0'for c in card))
→ 이분 탐색 함수에서 해당 값 찾고, while 문 안에서 같지 않은것 찾았을때 즉시 빠져나오는 break 해주지 않으면 시간초과
▶ 풀이방법 4: 딕셔너리만 사용
from collections import Counter
N = int(input())
lst = sorted(list(map(int, input().split()))) # 정렬
M = int(input())
card = list(map(int, input().split()))
dic = {}
for n in lst:
if n in dic: # 딕셔너리에 있으면
dic[n] += 1else: # 딕셔너리에 없으면
dic[n] = 1print(' '.join(str(dic[c]) if c in dic else'0'for c in card))
▶ 풀이방법 5: collections 라이브러리의 Counter() 사용
from collections import Counter
N = int(input())
lst = sorted(list(map(int, input().split()))) # 정렬
M = int(input())
card = list(map(int, input().split()))
counter = Counter(lst)
print(' '.join(str(counter[c]) if c in counter else'0'for c in card))
n, k = map(int, input().split()) # 문제의 조건: 항상 N<=K
lst = []
for _ inrange(n):
lst.append(int(input()))
low = 1# 시작을 1로 해야됨 !! (0으로 해버리면 mid로 나누는 부분에서 Error될 수 있음)
high = max(lst)
ans = -1while low<=high: # 이분탐색 조건 !!
mid = (low + high) // 2#print(low, mid, high)
sum_val = 0for a in lst:
sum_val += a//mid
if sum_val >= k: # k개 '이상' 이라면..(=문제의 조건)
ans = mid # mid값으로 ans를 업데이트 해나간다.
low = mid+1else:
high = mid-1print(ans)