코딩테스트 연습/programmers

[Programmers]그래프 > 순위(c++)

수기 2022. 1. 28. 13:24

https://programmers.co.kr/learn/courses/30/lessons/49191#

 

코딩테스트 연습 - 순위

5 [[4, 3], [4, 2], [3, 2], [1, 2], [2, 5]] 2

programmers.co.kr

플로이드 워셜 알고리즘(Floyd-Warshall Algorithm) 을 응용해서 풀었다.

 

1. floyd의 초깃값을 모두 -1로 초기화

2. result[i][0]는 이긴 선수, result[i][1]는 패배한 선수 이므로 floyd에서 가로를 기준으로, 자신이 이겼는지 졌는지를 나타낸다.

예시의 results[0][0] = 4, results[0][1] = 3 에서 4가 3을 이겼으므로

floyd[results[i][0]][results[i][1]] =1, floyd[results[i][1]][results[i][0]] = 0

3. floyd알고리즘을 응용해서, floyd[i][j]에서 i가 이긴선수, j가 진 선수 이므로

j기준으로 볼때 자신을 이긴 선수가(=i) 1일때, (floyd[i][j] == 1) 다른 선수에게 패배했다면 당연히 자신도 패배한다.

(floyd[i][k] == 0 다른선수에게 패배, floyd[j][k] = 0 자신도 패배.)

4. floyd[j][k] = 0라면 반대로 floyd[k][j] = 1 도 성립한다.

5. 사용하지 않는 0와 자기자신을 제외한 ㅡ 모든 선수들과의 경기 결과를 알 수 있다면 (floyd[i]의 -1개수가 2라면) answer++   

 


main포함 코드

#include <string>
#include <vector>
#include <cstring>
#include <algorithm>
using namespace std;

int solution(int n, vector<vector<int>> results) {
    int answer = 0;
    vector<vector<int>> floyd(n+1, vector<int>(n+1,-1));
    
    for(int i=0;i<results.size();i++){
        for(int j=0;j<results[i].size();j++){
            floyd[results[i][0]][results[i][1]] = 1;
            floyd[results[i][1]][results[i][0]] = 0;
        }
    }
    
    for(int i=1;i<n+1;i++){
        for(int j=1;j<n+1;j++){
            if(floyd[i][j] == 1){
                for(int k=1;k<n+1;k++){
                    //자신을 이긴 곳이, 다른 곳에게 패배(0) 라면 자신도 (0)
                    if(floyd[i][k] == 0) { floyd[j][k] = 0; floyd[k][j] = 1; }
                }
            }
        }
    }
    
    for(int i=1;i<n+1;i++)if(count(floyd[i].begin(), floyd[i].end(), -1) == 2)answer++;
    return answer;
}
int main(){
    
    int n = 4;
//    vector<vector<int>> results = {{4, 3}, {4, 2}, {3, 2}, {1, 2}, {2, 5}};
    vector<vector<int>> results = {{1, 2}, {2, 3}, {1, 4}};
    solution(n, results);
    return 0;
}

 


사용한 테스트케이스

4  /  [[1, 2], [2, 3], [1, 4]]  Return 1