bridge에서 popleft를 통해 한 칸 씩 왼쪽으로 옮겨간다. (rotate와 다름. rotate는 1->2->3->1 처럼 돌기 때문)
새롭게 들어갈 트럭의 무게와 현재 bridge의 무게를 더해서 견딜 수 있는지 확인한다.
견딜 수 있다면 새롭게 들어갈 트럭의 무게를 더하고
견딜 수 없다면 0을 더한다.
💻 풀이
# 최대 bridge_length대 올라갈 수 있음. (다리의 길이)
# weight만큼 버틸 수 있음.
# 다리에 완전히 오르지 않았다면 무게를 무시한다.
from collections import deque
def solution(bridge_length, weight, truck_weights):
time = 0
# 현재 올라간 트럭의 무게 합
weight_sum = 0
# bridge 크기만큼의 데큐 생성
bridge = deque([0 for i in range(bridge_length)])
while truck_weights:
time += 1
weight_sum -= bridge.popleft()
# 이번에 들어갈 트럭 무게 계산
truck = truck_weights[0]
if weight_sum + truck <= weight:
weight_sum += truck
bridge.append(truck_weights.pop(0))
else:
bridge.append(0)
# 마지막 트럭이 들어간 후 완전히 나올 때 까지의 시간 더해주기 (bridge_length)
return time + bridge_length
🧩 포인트
- deque를 사용해서 popleft, append로 실제 다리를 건너는 것처럼 한다.
- 처음에 현재 bridge의 무게를 구할 때 sum() 함수를 사용했는데, 이럴 경우 시간 초과가 나기 때문에 sum을 담을 변수를 생성한 후 계산을 해줘야 한다.
1. 회전해야하는 숫자들을 top, right, bottom, left순으로 리스트에 담는다. a. 단, bottom과 left는 역순으로 담는다.
2. deque의 rotate 함수를 활용해서 1칸씩 오른쪽으로 이동해준다.
3. 다시 top, right, bottom, left순으로 넣어준다. a. 단, bottom과 left는 역순으로 넣어준다.
💻 풀이
from collections import deque
def solution(rows, columns, queries):
items = [[y + x * columns for y in range(1, columns + 1)] for x in range(rows)]
minimum_list = []
for x1, y1, x2, y2 in queries:
x1 -= 1
y1 -= 1
x2 -= 1
y2 -= 1
# 위치 변경할 숫자들
change_list = []
# top
change_list.extend(items[x1][y1: y2])
# right
for x in range(x1, x2):
change_list.append(items[x][y2])
# bottom
change_list.extend(reversed(items[x2][y1 + 1: y2 + 1]))
# left
for x in range(x2, x1, -1):
change_list.append(items[x][y1])
# 최솟값 구하기
minimum_list.append(min(change_list))
# deque를 이용한 위치 변경
dq = deque(change_list)
dq.rotate(1)
# top, right, bottom, left 순으로 넣어주기
# top
for y in range(y1, y2):
items[x1][y] = dq.popleft()
# right
for x in range(x1, x2):
items[x][y2] = dq.popleft()
# bottom
for y in range(y2, y1, -1):
items[x2][y] = dq.popleft()
# left
for x in range(x2, x1, -1):
items[x][y1] = dq.popleft()
return minimum_list
1. 후보키가 될 수 있는 집합을 만든다. a. relation의 컬럼(column) 숫자를 가지고 만든다. b. 해당 결과는 (0), (1), ... (0, 1), (0, 2), ... (0, 1, 2, 3) 으로 나온다.
2. 만든 집합을 돌면서 해당 인덱스에 맞는 값들을 가지고 실제 집합을 만들어 준다.
3. 실제 집합 상태에서 중복 제거를 해준다. a. 유일성을 만족하는지 확인하기 위함이다.
4. 유일성을 만족한다면 (중복 제거 후에도 relation의 row길이와 같다면) a. answer 배열에 해당 인덱스 집합의 부분집합이 있는지 확인한다. b. 예를 들어, (0, 1)은 (0)을 포함하기 때문에 최소성을 만족하지 않는다. c. 부분집합에 해당하지 않으면 answer 배열에 해당 인덱스 집합을 더해준다.
💻 풀이
from itertools import combinations
def solution(relation):
# 가능한 인덱스 조합
index_combination = []
for r in range(1, len(relation[0]) + 1):
index_combination.extend(combinations(range(len(relation[0])), r))
answer = []
for comb in index_combination:
# 해당 인덱스를 사용한 실제 조합
tmp1 = []
for r in relation:
tmp2 = []
for c in comb:
tmp2.append(r[c])
# 이후에 2차원 중복제거를 위해 tuple로 변환 후 append
tmp1.append(tuple(tmp2))
# 유일성 확인
if len(set(tmp1)) == len(relation):
# 최소성 확인
check = True
for a in answer:
if set(a).issubset(comb):
check = False
break
if check: answer.append(comb)
return len(answer)
🧩 포인트
- 2차원 리스트를 중복제거 하기 위해서는 tuple을 사용해 1차원 리스트로 만들어 주고 set을 사용한다. - tuple은 중복 제거가 되지 않는다.
6. 해당 멜로디에 네오가 기억하는 부분이 있는지 확인한다. a. 샾이 붙은 데이터는 미리 제거한다. ㄱ. ABC#D에는 ABC와 ABC# 모두 포함될 수 있다. ㄴ. 네오가 기억하는 부분에 #를 더한 ABC#과 ABC##을 찾아서 미리 제거한다.
7. 네오가 기억하는 부분이 포함되면 match_list에 append해준다.
8. 재생시간 기준으로 역순 정렬한다. 만약 match_list가 비어있다면 (None)을 반환한다.
💻 풀이
# 음악이 시작한 시각, 끝난 시각, 음악 제목, 악보 정보
def solution(m, musicinfos):
match_list = []
for musicinfo in musicinfos:
start_time, end_time, title, sheet = musicinfo.split(",")
# sheet 변경
#1. 모든 문자열 분리 및 #붙이기
sheet = list(sheet)
for idx, item in enumerate(sheet):
if item == "#":
sheet[idx - 1] += "#"
# 샾 제거
sheet = [i for i in sheet if i != "#"]
# 분, 초 분리
start_hour, start_minute = start_time.split(":")
end_hour, end_minute = end_time.split(":")
# 재생 시간 계산
sub_hour = int(end_hour) - int(start_hour)
sub_minute = int(end_minute) - int(start_minute)
play_time = 60 * sub_hour + sub_minute
melody = sheet * (play_time // len(sheet)) + sheet[:play_time % len(sheet)]
# 샾이 붙은 데이터 제거
# ABC#D에는 ABC와 ABC# 모두 포함될 수 있음. 따라서 ABC#과 ABC##을 찾아서 미리 없앰.
check_melody = ''.join(melody).replace(m + "#", '')
if m in check_melody:
match_list.append({"playTime": play_time,
"title": title})
match_list = sorted(match_list, key= lambda x: x["playTime"], reverse= True)
if match_list == []:
return "(None)"
else:
return match_list[0]["title"]
2. 해당 배열에서 find를 사용하여 skill의 각각의 원소에 해당하는 인덱스를 가져온다.
3. 만약 find의 리턴 값이 -1이라면 (해당 배열에 값이 없는 경우) skills의 길이를 넣어준다. a. -1이 앞에 있는 경우 미통과이기 때문에 순서를 뒤바꿀 수 있는 큰 값을 넣어주는 것이다.
4. 정렬했을 때 순서가 바뀌지 않는다면 통과!
💻 풀이
def solution(skill, skill_trees):
answer = 0
for skills in skill_trees:
token_index_list = list(map(lambda x: skills.find(x), skill))
token_index_list = list(map(lambda x: len(skills) if x == -1 else x, token_index_list))
if token_index_list == sorted(token_index_list):
answer += 1
return answer
print(solution("CBD", ["BACDE", "CBADF", "AECB", "BDA"]))
"""
token_index_list 결과가 다음과 같으면,
[2, 0, 3] -> 미통과
[0, 1, 3] -> 통과
[2, 3, -1] -> 통과
[-1, 0, 1] -> 미통과
-1이 있는 두 가지를 구별할 방법은 -1인 경우 큰 값을 넣어주기!
"""
한 건물 또는 인접한 건물군 내에 있는 네트워크는 하나의 LAN으로 간주되며 집이나 빌딩 안에 있는 사무실 등 지리적으로 제한된 곳에서 컴퓨터와 프린터, 스캐너 등을 연결할 수 있는 네트워크이다.
서로 다른 LAN을 연결하여 사용할 수 있다.
📌 도시 지역 네트워크 (MAN, Metropolitan Area Network)
LAN보다 넓은 영역이고 WAN보다 작은 영역을 커버한다.
떨어져 있지만 동일하거나 다른 도시에 상주하는 두 대 이상의 컴퓨터를 연결한다.
예시 고객에게 고속 DSL 회선을 제공할 수 있는 회사의 일부 네트워크나 케이블 TV 네트워크가 있다. 지역 또는 도시 내에 위치한 다양한 경찰서를 서로 연결하는 데 사용할 수 있다. 경찰관은 인터넷 연결 없이 쉽게 통신할 수 있고 중요한 데이터와 긴급 메시지를 네트워크를 통해 신속하게 전달할 수 있다.
📌 광역 네트워크 (WAN, Wide Area Network)
두 개 이상의 근거리 네트워크를 넓은 지역에 걸쳐 연결하는 것이다.
근거리 네트워크에 포함되지 않은 멀리 떨어진 컴퓨터 사이에서도 광역 네트워크를 이용하여 서로 통신할 수 있다.
LAN보다 오류 발생 확률이 크고, 속도는 느리며, 비용은 많이 든다.
예시 어떤 기업의 본사는 서울에 있고 생산 공장은 지방에 있을 수 있다. 이 둘 간에 데이터와 프로그램 등을 공유하려고 기존 전화선에 라우터를 연결하여 광역 네트워크를 구성하기도 한다.
📌 인트라넷 (Intranet)
인터넷에서 사용하는 회선과 여러 기반 기술을 이용하여 구축하는 사설 네트워크이다.
기업에서 내부망, 외부망을 따로 관리하는 경우가 있는데 이러한 경우 내부망이 바로 인트라넷이다.
예시 각 지방에 분산된 대학 캠퍼스들을 전용회선을 이용하여 네트워크로 연결한다면 지불 비용이 많이 들 것이다. 하지만 인터넷을 이용하면 쉽게 해결할 수 있다.
아무리 멀리 떨어져 있어도 각 지방의 캠퍼스들을 ISP까지만 연결하면 인터넷을 이용하여 저렴한 비용으로 사설 네트워크를 구축할 수 있다.