알고리즘 문제/프로그래머스

순위 [Lv. 3]

우대비 2024. 9. 23. 22:53
반응형
 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

N명의 권투선수가 참여한 권투 대회, 심판은 경기 결과를 가지고 순위를 매기려하는데 몇몇 경기 결과를 분실하여 정확하게 순위를 매길 수 없는 상황입니다. 남아있는 결과를 통해 순위를 확실히 알 수 있는 사람이 몇명인지 찾아주세요.

(A선수가 B선수를 이기고 B선수가 C선수를 이기면 A선수는 무조건 C선수를 이깁니다)

 

풀이방법

플로이드-워샬 알고리즘을 사용하여 풀 수 있겠습니다. 순위라고 생각하지 않고 길찾기라고 생각하면 쉽습니다.

A선수와 모든 선수와의 결과를 알 수 있다면 A선수는 순위를 명확히 확인할 수 있습니다. 바꿔서 생각하면

A지점에서부터 모든 지점으로 길찾기가 가능한지를 찾으면 되겠죠.

 

대결 결과를 담을 2차원 배열을 만들어주고

array[A선수][B선수] = A선수가 이겼다면 1, 졌다면 -1;

위와 같이 초기값을 설정해줍니다.

 


A선수가 B선수를 이기고 B선수가 C선수를 이겼다면 A선수는 C선수를 이길 수 있습니다. 반대로, 

A선수가 B선수에게 이고 B선수가 C선수에게 졌다면 A선수는 C선수에게 이길 수 없습니다.

 

다른 상황으로

A선수가 B선수를 이기고 B선수가 C선수에게 졌다면 A선수와 C선수의 결과는 알 수 없습니다. 반대로,

A선수가 B선수에게 지고 B선수가 C선수에게 이겼다면 A선수와 C선수의 결과는 알 수 없습니다. 


즉 플로이드-워셜에서 길찾기가 가능한 부분은 A > B && B > C 이거나 A < B && B < C 일 때 입니다.

 

정답 코드

#include <string>
#include <vector>

using namespace std;

int solution(int n, vector<vector<int>> results) {
    vector<vector<int>> v(n, vector<int>(n, 0));
    
    for(auto& result : results)
    {
        v[result[0]-1][result[1]-1] = 1;
        v[result[1]-1][result[0]-1] = -1;
    }

    for (int k = 0; k < n; k++)
    {
        for (int i = 0; i < n; i++)
        {
            for (int j = 0; j < n; j++)
            {
                if (v[i][k] != 0 && v[i][k] == v[k][j])
                    v[i][j] = v[i][k];
            }
        }
    }
    
    int answer = 0;
    for (int i = 0; i < n; i++)
    {
        int cnt = 0;
        for (int j = 0; j < n; j++)
        {
            if (v[i][j] == 0)
                cnt++;
        }
        if (cnt == 1)
            answer++;
    }
    return answer;
}

 

반응형
LIST

'알고리즘 문제 > 프로그래머스' 카테고리의 다른 글

프로그래머스-길찾기 게임[Lv. 3] (C++)  (0) 2024.09.26
자물쇠와 열쇠 [Lv. 3]  (0) 2024.09.25
가장 긴 팰린드롬 [Lv. 3]  (0) 2024.09.20
입국심사 [Lv. 3]  (0) 2024.09.19
섬 연결하기 [Lv. 3]  (1) 2024.09.18