일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 4기
- 구현
- 부스트캠프
- cs50
- 서버
- 2021 Dev-matching 웹 백엔드 개발자
- 서블릿
- Naver boostcamp
- boostcourse
- 파이썬
- 장고
- Django
- 프로그래밍
- 네이버
- Naver boostcourse
- 대회
- 백엔드
- 프로그래머스
- 백준
- P Stage
- BOJ
- 웹 프로그래밍
- 풀스택
- Customer service 구현
- QNA 봇
- AI Tech 4기
- AI Tech
- sts
- 레벨2
- 웹
- Today
- Total
daniel7481의 개발일지
[BOJ] 17616 등수 찾기 본문
https://www.acmicpc.net/problem/17616
문제
KOI 본선 대회에 N명의 학생이 참가했다. 이 학생들을 각각 1부터 N까지 정수로 표현하자. 대회가 끝나고 성적을 발표하는데, 이 대회는 전체 학생의 등수를 발표 하는 대신, 두 학생 A, B가 대회 본부에 찾아가면 본부는 두 학생 중 어느 학생이 더 잘 했는지를 알려준다. 둘 이상의 학생이 동점인 경우는 없다.
자신의 전체에서 등수가 궁금한 학생들은 둘 씩 짝을 지어서 대회 본부에 총 M번 질문을 했다. 여러분은 등수를 알고 싶은 학생 X와 대회 본부의 질문에 대한 답들 로부터 이 학생 X의 등수 범위를 찾아서 출력한다. 질문에 대한 답으로 알 수 있는 최대한 정확한 답을 출력한다.
입력
표준 입력으로 다음 정보가 주어진다. 첫 번째 줄에 세 정수 N, M, X가 공백을 사이에 두고 주어진다. (2 ≤ N ≤ 105, 1 ≤ M ≤ min(N(N-1)/2, 5×105), 1 ≤ X ≤ N) . 다음 M 줄에는 각각 두 정수 A, B가 주어지는데, 이 뜻은 학생 A가 학생 B보다 더 잘했다는 뜻이다. 같은 A, B가 둘 이상의 줄에 주어지는 경우는 없고, 입력된 값이 정확함이 보장된다.
출력
표준 출력으로 두 정수 U, V (1 ≤ U ≤ V ≤ N)를 출력한다. 이는 학생 X의 가능한 가장 높은 등수가 U, 가능한 가장 낮은 등수가 V임을 나타낸다. 만약 학생 X의 가능한 등수가 정확하게 하나라면, U = V이다.
서브태스크
1 | 12 | N ≤ 10 |
2 | 11 | N ≤ 1,000, M = N(N-1)/2 |
3 | 34 | N ≤ 1,000 |
4 | 43 | 원래의 제약조건 이외에 아무 제약조건이 없다. |
풀이
서브 태스크 문제는 all or nothing이기 때문에 항상 떨린다. 이 문제는 처음에는 위상정렬을 활용할까 생각했는데, 곧 학생들간에 순위는 트리 구조가 아니므로 그냥 bfs를 사용하기로 하였다. 제일 높은 순위와 제일 낮은 순위를 구해야하는데, 가장 높은 순위는 위에 몇명이 있는지를 구하면 가장 높은 순위를 구할 수 있고, 가장 낮은 순위는 자기 밑에 몇명이 있는지만 구하면 구할 수 있었다. 메모리 낭비가 좀 심할수도 있지만 두 학생의 관계가 주어졌을 때, 자기보다 높은 학생들을 구하는 up 배열과 낮은 학생을 구하는 down배열을 선언한 후 넣어주었다. 그 다음 두 가지 경우에 대하여 bfs를 돌아주었는데, 새로운 인물이 나올 때마다 up_people과 down_people에 하나씩 더해줌으로써 자기보다 위에 있는 사람과 자기보다 아래에 있는 사람들의 수를 구하였다. 그 후에 순위는 1등부터 있으므로 up_people+1을 출력. n-down_people을 출력하였다.
import sys
from collections import deque
n, m, x = map(int, input().split()) #사람 수, 관계의 수, 순위를 구하려는 사람
up = [[]for _ in range(n+1)] #자기보다 높은 사람들
down = [[]for _ in range(n+1)] #자기보다 낮은 사람들
for _ in range(m):
p1, p2 = map(int, input().split())
up[p2].append(p1)#자기보다 높은 사람을 요소로 삽입
down[p1].append(p2)#자기보다 낮은 사람을 요소로 삽입
q = deque()
visited = [False for _ in range(n+1)]
q.append(x)
up_people = 0
while q:
v = q.popleft()
for a in up[v]:
if not visited[a]:
q.append(a)
up_people += 1 #x보다 순위가 높은 사람들의 수
visited[a] = True
q = deque()
visited = [False for _ in range(n+1)]
q.append(x)
down_people = 0
while q:
v = q.popleft()
for a in down[v]:
if not visited[a]:
q.append(a)
down_people += 1 #x보다 순위가 낮은 사람들의 수
visited[a] = True
print(up_people+1, end = ' ')
print(n-down_people)
'BOJ' 카테고리의 다른 글
[BOJ] 19236 청소년 상어 (0) | 2021.12.24 |
---|---|
[BOJ] 17140 이차원 배열과 연산 (0) | 2021.12.24 |
[BOJ] 2193 이친수 (0) | 2021.12.16 |
[BOJ] 10844 쉬운 계단 수 (0) | 2021.12.16 |
[BOJ] 17135 캐슬 디펜스 (0) | 2021.12.16 |