티스토리 뷰

문제설명은 더보기를 눌러주세요

더보기

문제 링크 : programmers.co.kr/learn/courses/30/lessons/49191

문제 설명

n명의 권투선수가 권투 대회에 참여했고 각각 1번부터 n번까지 번호를 받았습니다. 권투 경기는 1대1 방식으로 진행이 되고, 만약 A 선수가 B 선수보다 실력이 좋다면 A 선수는 B 선수를 항상 이깁니다. 심판은 주어진 경기 결과를 가지고 선수들의 순위를 매기려 합니다. 하지만 몇몇 경기 결과를 분실하여 정확하게 순위를 매길 수 없습니다.

선수의 수 n, 경기 결과를 담은 2차원 배열 results가 매개변수로 주어질 때 정확하게 순위를 매길 수 있는 선수의 수를 return 하도록 solution 함수를 작성해주세요.

제한사항

  • 선수의 수는 1명 이상 100명 이하입니다.
  • 경기 결과는 1개 이상 4,500개 이하입니다.
  • results 배열 각 행 [A, B]는 A 선수가 B 선수를 이겼다는 의미입니다.
  • 모든 경기 결과에는 모순이 없습니다.

입출력 예

n    results    return
5 [[4, 3], [4, 2], [3, 2], [1, 2], [2, 5]] 2

입출력 예 설명

2번 선수는 [1, 3, 4] 선수에게 패배했고 5번 선수에게 승리했기 때문에 4위입니다.
5번 선수는 4위인 2번 선수에게 패배했기 때문에 5위입니다.

 

-풀이-

1. 플로이드-와샬 알고리즘을 사용하는 문제입니다.
    (플로이드-와샬 알고리즘은, 모든 정점에서 모든 정점까지의 최단 거리를 알고싶을 때 사용합니다)
    (또한, 거쳐가는 정점을 기준으로 탐색합니다. -> 아래 코드부분에서 변수 k)

2. 2차원 배열을 하나 선언합니다. (아래 코드상으론 map, map[i][j]는 x가 y를 이긴다는 것을 의미합니다)
    x가 y를 이겼고, y가 z를 이겼다면 x는 z를 이긴다는 것을 알 수 있습니다.
    이렇게 중간에 낀 y를 지나쳐가는 정점으로 보는 방식입니다. 

3. 플로이드 와샬 알고리즘을 적용시킨 후, 그 사람이 이길 사람(map[i][j]) 과 질 사람(map[j][i])의
    수의 합이 n-1과 같다면, 순위를 확실히 알 수 있습니다. 
    
    

-코드(C++)-

#include <string>
#include <vector>
#include <iostream>
#include <cstring>
int map[101][101];
using namespace std;
int solution(int n, vector<vector<int>> results) {
    int answer = 0, N = n;
    memset(map, 0, sizeof(map));
    for(auto i : results) map[i[0]][i[1]] = 1;
    for(int k=1; k<=N; k++){
        for(int i=1; i<=N; i++){
            for(int j=1; j<=N; j++){
                if(map[i][k] && map[k][j]) map[i][j] = 1; //i->j로 갈때, k를 거쳐가는 길이 있다면
            }
        }
    }
    for(int i=1; i<=N; i++){
        int cnt = 0;
        for(int j=1; j<=N; j++){
            if(map[i][j] || map[j][i]) cnt++; //i가 이길 사람 또는 질 사람
        }
        if(cnt == N-1) answer++;
    }
    return answer;
}

-코드(Swift)-

import Foundation

func solution(_ n:Int, _ results:[[Int]]) -> Int {
    var answer : Int = 0
    var map : [[Int]] = Array(repeating: Array(repeating: 0, count: 101), count : 101)
    for i in results {
        map[i[0]][i[1]] = 1
    }
    for k in 1...n{
        for i in 1...n{
            for j in 1...n{
                if map[i][k] == 1 && map[k][j] == 1{
                    map[i][j] = 1
                }
            }
        }
    }
    for i in 1...n{
        var cnt : Int = 0
        for j in 1...n{
            if map[i][j] == 1 || map[j][i] == 1 {
                cnt+=1
            }
        }
        if cnt == n-1 {
            answer+=1
        }
    }
    
    return answer
}
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday