일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 백준
- 몽골
- 알고리즘
- 게르
- 몽골요리
- 아부다비
- 파이썬
- SWEA
- 여행
- 몽골 고기
- 테를지
- 코로나
- 헬스
- 테를지국립공원
- algorithm
- 칭기스칸 동상
- ICT봉사단
- 한 줄로 서기
- 초원
- 소프트웨어 아카데미
- 교환학생
- 칭기즈칸
- 몽골 헬스장
- 월드프렌즈 ICT 봉사단
- 담슈타트
- 독일
- 월드프렌즈
- LG글로벌챌린저
- Python
- 울란바토르
- Today
- Total
맛있는물회
[맛있는물회] [파이썬] <백준 알고리즘> 2458번 "키 순서" 본문
문제 조건
1번부터 N번까지 번호가 붙여져 있는 학생들에 대하여 두 학생끼리 키를 비교한 결과의 일부가 주어져 있다. 단, N명의 학생들의 키는 모두 다르다고 가정한다. 예를 들어, 6명의 학생들에 대하여 6번만 키를 비교하였고, 그 결과가 다음과 같다고 하자.
- 1번 학생의 키 < 5번 학생의 키
- 3번 학생의 키 < 4번 학생의 키
- 5번 학생의 키 < 4번 학생의 키
- 4번 학생의 키 < 2번 학생의 키
- 4번 학생의 키 < 6번 학생의 키
- 5번 학생의 키 < 2번 학생의 키
이 비교 결과로부터 모든 학생 중에서 키가 가장 작은 학생부터 자신이 몇 번째인지 알 수 있는 학생들도 있고 그렇지 못한 학생들도 있다는 사실을 아래처럼 그림을 그려 쉽게 확인할 수 있다. a번 학생의 키가 b번 학생의 키보다 작다면, a에서 b로 화살표를 그려서 표현하였다.
1번은 5번보다 키가 작고, 5번은 4번보다 작기 때문에, 1번은 4번보다 작게 된다. 그러면 1번, 3번, 5번은 모두 4번보다 작게 된다. 또한 4번은 2번과 6번보다 작기 때문에, 4번 학생은 자기보다 작은 학생이 3명이 있고, 자기보다 큰 학생이 2명이 있게 되어 자신의 키가 몇 번째인지 정확히 알 수 있다. 그러나 4번을 제외한 학생들은 자신의 키가 몇 번째인지 알 수 없다.
학생들의 키를 비교한 결과가 주어질 때, 자신의 키가 몇 번째인지 알 수 있는 학생들이 모두 몇 명인지 계산하여 출력하는 프로그램을 작성하시오.
Input
첫째 줄에 학생들의 수 N (2<=N<=500)과 두 학생 키를 비교한 횟수 M (0<=M<=N(N-1)/2)이 주어진다. 다음 M개의 각 줄에는 두 학생의 키를 비교한 결과를 나타내는 두 양의 정수 a와 b가 주어진다. 이는 번호가 a인 학생이 번호가 b인 학생보다 키가 작은 것을 의미한다.
Output
자신이 키가 몇 번째인지 알 수 있는 학생이 모두 몇 명인지를 출력한다.
생각한 아이디어
간단한 플로이드 와샬 문제이다.
사실 플로이드 와샬이 아닌 다른 탐색방법으로 접근이 가능할 것 같은데 N이 500까지라서 시간복잡도안에 돌아갈지는 의문이다.
어쨌든 현재 문제에서 원하는 조건은 모든 노드들을 확인하여 자신이 어느 위치에 있는지 즉, 자신에게 들어오는 노드들의 수와 자신이 갈 수 있는 노드들의 수를 아는 것이 핵심이다.
따라서 모든 노드 - 모든 노드 의 경우를 알기 위해서는 플로이드 와샬 알고리즘을 사용하는 것이 편리하다.
3중포문의 아주 직관적인 플로이드 와샬 알고리즘을 사용하였고, 위치를 판단하는 방법은 아래와 같다.
1. 모든 노드 - 모든 노드 의 2차원 배열을 생성하여 구성한다.
2. i 자신이 갈 수 있는 노드를 확인한다. 즉, 초기값을 INF 로 두고 만약 구성된 이차원배열에서 i->j 값이 INF라면 갈 수 없는 것이기 때문에 제외한다.
3. i 자신이 갈 수 없는 노드들을 미리 저장해두고 그 값들을 다시 체크하면서 그 값들이 i 로 갈 수 있는지를 확인한다.
4. 만약 모두 i로 갈 수 있다면 i는 자신의 위치를 알 수 있다.
소스코드
#2458 키 순서
import sys
from collections import deque
input=sys.stdin.readline
inf = 2*32
n,m=map(int,input().split())
arr=[[inf for _ in range(n+2)] for _ in range(n+2)]
for _ in range(m):
a,b=map(int,input().split())
arr[a][b]=1
for i in range(1,n+1):arr[i][i]=0
for k in range(1,n+1):
for i in range(1,n+1):
for j in range(1,n+1):
arr[i][j]=min(arr[i][j],arr[i][k]+arr[k][j])
res=[]
for i in range(1,n+1):
tmp=[]
for j in range(1,n+1):
if arr[i][j]==inf: #못간다는 의미
tmp.append(j)
flag=0
for t in tmp:
if arr[t][i]==inf:
flag=1
break
if flag==0:
res.append(i)
print(len(res))
*파이썬 문법 정리
'IT > 알고리즘' 카테고리의 다른 글
[맛있는물회] [파이썬] <백준 알고리즘> 4864번 "숫자카드" (1) | 2020.07.05 |
---|---|
[맛있는물회] [파이썬] <백준 알고리즘> 4864번 "숫자카드" (0) | 2020.07.02 |
[맛있는물회] [파이썬] <백준 알고리즘> 1238번 "파티" (0) | 2020.07.01 |
[맛있는물회] [파이썬] <백준 알고리즘> 11404번 "플로이드" (0) | 2020.06.30 |
[맛있는물회] [파이썬] <백준 알고리즘> 2660번 "회장뽑기" (0) | 2020.06.30 |