본문 바로가기
알고리즘/백준

BOJ(C++) / 백준 2458 : 키 순서

by clean_h 2021. 10. 10.
728x90

백준 2458 : 키 순서

https://www.acmicpc.net/problem/2458

 

2458번: 키 순서

1번부터 N번까지 번호가 붙여져 있는 학생들에 대하여 두 학생끼리 키를 비교한 결과의 일부가 주어져 있다. 단, N명의 학생들의 키는 모두 다르다고 가정한다. 예를 들어, 6명의 학생들에 대하여

www.acmicpc.net

 

문제

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번을 제외한 학생들은 자신의 키가 몇 번째인지 알 수 없다. 

학생들의 키를 비교한 결과가 주어질 때, 자신의 키가 몇 번째인지 알 수 있는 학생들이 모두 몇 명인지 계산하여 출력하는 프로그램을 작성하시오.

 

입력

첫째 줄에 학생들의 수 N (2 ≤ N ≤ 500)과 두 학생 키를 비교한 횟수 M (0 ≤ M ≤ N(N-1)/2)이 주어진다. 다음 M개의 각 줄에는 두 학생의 키를 비교한 결과를 나타내는 두 양의 정수 a와 b가 주어진다. 이는 번호가 a인 학생이 번호가 b인 학생보다 키가 작은 것을 의미한다. 

 

출력

자신이 키가 몇 번째인지 알 수 있는 학생이 모두 몇 명인지를 출력한다. 

 

코드

//백준 2458 키 순서
#include <iostream>

using namespace std;

int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);

	int N, M;
	cin >> N >> M;

	int height[501][501] = { 0, };

	for (int i = 0; i < M; i++) {
		int a, b;
		cin >> a >> b;
		height[a][b] = 1;
	}

	//플로이드 와샬
	for (int k = 1; k <= N; k++) {
		for (int i = 1; i <= N; i++) {
			for (int j = 1; j <= N; j++) {
				if (height[i][k] && height[k][j]) {
					height[i][j] = 1;
				}
			}
		}
	}

	int answer = 0;
	for (int i = 1; i <= N; i++) {
		int count = 0;
		for (int j = 1; j <= N; j++) {
			if (height[i][j] == 1 || height[j][i] == 1) //내가 이긴사람이 있거나 나를 이긴사람이 있거나
				count++;
		}
		if (count == N - 1)
			answer++;
	}

	cout << answer << "\n";


	return 0;
}

//걸린시간 1시간

 

설명

  • 플로이드 와샬 알고리즘을 사용한다. 
  • 이차원 배원 height를 생성해서 자신보다 우위에 있는 사람을 배열에 저장한다.
  • floyd warshall를 사용하여 모든 선수에 대해 우위에 있으면 1을 배열에 저장한다.
  • floyd warshall은 가중 그래프에서 최단 경로들을 찾는 알고리즘이다. 모든 노드 간의 최단 경로의 길이를 찾을 수 있다. 
  • 1번부터 n번까지 우위를 가릴 수 있는 사람이 본인을 제외한 전부라면 정확하게 순위를 매길 수 있다.  
  • 내가 이긴 사람이거나 나를 이긴 사람이라면 count를 증가하여 count가 N-1(본인 제외)과 같다면 자신의 키가 몇 번째인지 알 수 있다.

 

고찰

걸린 시간 : 1시간

프로그래머스에서 비슷한 문제가 있어서 해결법을 쉽게 생각해낼 수 있었다.

하지만 아직 3중 반복문을 생각하는데는 조금 시간이 걸린다.

2021.08.09 - [알고리즘/프로그래머스] - 알고리즘(C++) / 프로그래머스 level 3 : 순위

 

알고리즘(C++) / 프로그래머스 level 3 : 순위

level 3 : 순위 https://programmers.co.kr/learn/courses/30/lessons/49191?language=cpp 코딩테스트 연습 - 순위 5 [[4, 3], [4, 2], [3, 2], [1, 2], [2, 5]] 2 programmers.co.kr 코드 //프로그래머스 순위..

se-jung-h.tistory.com

 

난이도(solved)

Gold 4

728x90

댓글