Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
Tags
- 개인회고
- dfs
- 알고리즘스터디
- 글또
- Level2_PStage
- 그래프이론
- Level1
- 다시보기
- 프로그래머스
- 주간회고
- U_stage
- 단계별문제풀이
- 구현
- Level2
- ODQA
- mrc
- python3
- 백준
- 정렬
- 기술면접
- 알고리즘_스터디
- dp
- 부스트캠프_AITech_3기
- 부스트캠프_AITech3기
- 이진탐색
- 파이썬 3
- 최단경로
- 백트랙킹
- 이코테
- 그리디
Archives
- Today
- Total
국문과 유목민
(Week8)[서로소] 공항 본문
주간 코딩스터디 때 푼 문제들을 정리하고 있습니다. 구체적인 문제에 대한 정보는 게시글 내 링크를 살펴봐주세요
소요시간: 30분
1. 문제 설명
https://www.acmicpc.net/problem/10775
10775번: 공항
예제 1 : [2][?][?][1] 형태로 도킹시킬 수 있다. 3번째 비행기는 도킹시킬 수 없다. 예제 2 : [1][2][3][?] 형태로 도킹 시킬 수 있고, 4번째 비행기는 절대 도킹 시킬 수 없어서 이후 추가적인 도킹은 불
www.acmicpc.net
- 문제를 이해하기가 좀 어려웠었는데, P개의 비행기가 순서대로 도착할 예정이며, 당신은 i번째 비행기를 1번부터 gi (1 ≤ gi ≤ G) 번째 게이트중 하나에 영구적으로 도킹... 부분을 제대로 이해하지 못했기 때문이었다.
- 이를 다시 이해해보자면, 1번째 비행기가 4게이트에 할당된다면 1~4의 게이트 중 하나에만 도킹하면 되는 것이다.
2. 접근 방식
- 예제 1번의 경우 비행기가 [4, 1, 1] 순서라면 첫번째 비행기는 1~4번 게이트, 두번째 비행기는 1번 게이트, 세번째 비행기는 1번 게이트에 도킹할 수 있다.
- 따라서 높은 번호의 게이트에 접근할 수 있는 비행기들은 최대한 높은 번호의 게이트에 도킹해야 한다.
- 따라서 첫번째 비행기는 4번 게이트에 도킹하고, 두번째 비행기는 1번 게이트에 도킹한다면, 세번째 비행기는 1번 게이트에 도킹할 수 없어서 거기서 종료가 된다.
따라서 위와 같이 문제를 이해한다면 서로소 알고리즘을 활용해서 루트 노드가 0을 가리키게 하면 된다. 처음에는 그냥 부모노드의 값을 -1씩 했는데 그렇게 하면 안된다. 서로소 알고리즘을 활용해야 하는 이유는 다음과 같은 경우 때문이라고 생각한다.
- 첫번째 비행기가 4번 게이트에 도킹을 했다. (다음에 4번 게이트에 도킹하려는 비행기는 3번 게이트에 도킹해야 한다)
- 두번째 비행기가 3번 게이트에 도킹을 했다면, 다음 비행기는 2번 게이트에 도킹해야 한다.
- 다음으로 새번째 비행기가 4번 게이트에 도킹을 하려고 한다면, 첫번째 때문에 3번 게이트에 도킹해야 한다. 하지만 두번째 때문에 3번 게이트에도 도킹을 못한다. 따라서 2번 게이트에 도킹을 해야 한다.
내 생각에는 위와 같은 상황 때문에 union_parent 연산이 필요하다고 생각한다. 게이트 3과 게이트 4의 parent를 union해줌으로써 모두 게이트 2를 가리킬 수 있도록 해야하기 때문에 서로소 알고리즘을 활용해야 한다.
3. 코드
import sys # sys.stdin.readline
gate = [i for i in range(int(input())+1)]
plane = []
for i in range(int(input())):
plane.append(int(input()))
def find_parent(parent, x):
if parent[x] != x:
parent[x] = find_parent(parent, parent[x])
return parent[x]
def union_parent(parent, a, b):
a = find_parent(parent, a)
b = find_parent(parent, b)
parent[a] = b
count = 0
for g in plane:
x = find_parent(gate, g)
if x == 0:
break
else:
union_parent(gate, x, x-1)
count += 1
print(count)
4. 코멘트
- 백준에서는 input이 많이 들어가는 경우 시간 효율성 문제가 생긴다. 따라서 sys 라이브러리의 stdin.readline함수를 사용해줘야 한다. 해당 문제에서도 그냥 input으로 하면 안되는 문제가 발생했다.
- 코딩 스터디를 진행하면서 루트 노드를 부모 노드라고 얘기해서 전달에 오류가 생겼었다. 용어도 신경써서 얘기해야 한다.
- 백준 골드2짜리 문제였지만, 서로소 알고리즘을 이해했다면 쉽게 풀 수 있는 문제였다.
- 원래는 union_parent함수에서 조건문을 넣어줬었는데, 입력으로 들어오는 a, b의 순서가 항상 b가 a보다 작기 때문에 a의 부모노드로 b의 부모노드를 가리키기만 하면 된다. 따라서 조건문이 필요가 없어 뺐다.
'알고리즘_코딩테스트 > 주간코딩 스터디 (주코스)' 카테고리의 다른 글
(Week8)[플로드이드-워셜] 공항 (0) | 2022.07.17 |
---|---|
(Week7)[Dijkestra] 배달 (0) | 2022.07.08 |
(Week7)[Dijkestra] 가장 먼 노드 (0) | 2022.07.08 |
(Week6)[DP] Two Egg Drop (다시보기) (0) | 2022.07.07 |
(Week6)[DP] 택배포장 (0) | 2022.07.07 |