https://www.acmicpc.net/problem/2617
2617번: 구슬 찾기
모양은 같으나, 무게가 모두 다른 N개의 구슬이 있다. N은 홀수이며, 구슬에는 번호가 1,2,...,N으로 붙어 있다. 이 구슬 중에서 무게가 전체의 중간인 (무게 순서로 (N+1)/2번째) 구슬을 찾기 위해서
www.acmicpc.net
문제
모양은 같으나, 무게가 모두 다른 N개의 구슬이 있다. N은 홀수이며, 구슬에는 번호가 1,2,...,N으로 붙어 있다. 이 구슬 중에서 무게가 전체의 중간인 (무게 순서로 (N+1)/2번째) 구슬을 찾기 위해서 아래와 같은 일을 하려 한다.
우리에게 주어진 것은 양팔 저울이다. 한 쌍의 구슬을 골라서 양팔 저울의 양쪽에 하나씩 올려 보면 어느 쪽이 무거운가를 알 수 있다. 이렇게 M개의 쌍을 골라서 각각 양팔 저울에 올려서 어느 것이 무거운가를 모두 알아냈다. 이 결과를 이용하여 무게가 중간이 될 가능성이 전혀 없는 구슬들은 먼저 제외한다.
예를 들어, N=5이고, M=4 쌍의 구슬에 대해서 어느 쪽이 무거운가를 알아낸 결과가 아래에 있다.
- 구슬 2번이 구슬 1번보다 무겁다.
- 구슬 4번이 구슬 3번보다 무겁다.
- 구슬 5번이 구슬 1번보다 무겁다.
- 구슬 4번이 구슬 2번보다 무겁다.
위와 같이 네 개의 결과만을 알고 있으면, 무게가 중간인 구슬을 정확하게 찾을 수는 없지만, 1번 구슬과 4번 구슬은 무게가 중간인 구슬이 절대 될 수 없다는 것은 확실히 알 수 있다. 1번 구슬보다 무거운 것이 2, 4, 5번 구슬이고, 4번 보다 가벼운 것이 1, 2, 3번이다. 따라서 답은 2개이다.
M 개의 쌍에 대한 결과를 보고 무게가 중간인 구슬이 될 수 없는 구슬의 개수를 구하는 프로그램을 작성하시오.
입력
첫 줄은 구슬의 개수를 나타내는 정수 N(1 ≤ N ≤ 99)과 저울에 올려 본 쌍의 개수 M(1 ≤ M ≤ N(N-1)/2)이 주어진다. 그 다음 M 개의 줄은 각 줄마다 두 개의 구슬 번호가 주어지는데, 앞 번호의 구슬이 뒤 번호의 구슬보다 무겁다는 것을 뜻한다.
출력
첫 줄에 무게가 중간이 절대로 될 수 없는 구슬의 수를 출력 한다.
풀이
1. 무거운 구슬 - 가벼운 구슬 이렇게 간선이 주어 질 때, 각각 나보다 무거운 구슬을 저장하는 list와 가벼운 무거운 구슬을 저장하는 list를 별개로 만든다. ( 양쪽 간선을 모두 표시하는게 아닌, 각각 표시한다!)
2. 기초적인 dfs를 생성한다. (계속 타고 타고 방문하면서, count만 해준다!)
그러면, dfs가 탐색을 한 횟수가 나보다 큰 or 작은 구슬의 개수가 된다.
3. 그 개수가 (1+n)/2 보다 크거나 같다면, 중간값이 될 수 없다!
코드
import sys
bead_N, edge = map(int, sys.stdin.readline().strip().split())
# 나보다 무거운 구슬을 담아 놓은 리스트와 가벼운 구슬을 담아 놓는 리스트를 구분해서 만듦!
# dfs를 통해 나보다 무거운 or 가벼운 구슬이 몇개인지 파악하기 위함
heavy_bead_list = [[] for _ in range(bead_N + 1)]
light_bead_list = [[] for _ in range(bead_N + 1)]
for _ in range(edge):
heavy, light = map(int, sys.stdin.readline().strip().split())
heavy_bead_list[light].append(heavy)
light_bead_list[heavy].append(light)
# 평범한 dfs, 계속 타고 가면 몇개의 node까지 탈 수 있는지 return 해줌
def dfs(node, list):
global visited
global check
visited[node] = 1
for bead in list[node]:
if visited[bead] == 0:
check += 1
dfs(bead, list)
count = 0
md = (bead_N + 1) / 2
for i in range(1, bead_N + 1):
visited = [0] * (bead_N + 1)
check = 0
dfs(i, heavy_bead_list)
if (check >= md):
count += 1
check = 0
dfs(i, light_bead_list)
if check >= md:
count += 1
print(count)
'프로그래머가 되자!!!! > 알고리즘 공부!' 카테고리의 다른 글
[BOJ]2583. 영역구하기 (python) (0) | 2021.08.25 |
---|---|
[BOJ]2637. 장난감조립 (python) (0) | 2021.08.25 |
[BOJ]2623. 음악프로그램 (python) (0) | 2021.08.24 |
[BOJ]1766. 문제집 (python) (0) | 2021.08.24 |
[BOJ]2294. 동전2 (1) | 2021.08.23 |