알고리즘 문제

백준 1946번) 신입 사원 (JAVA)

roder 2022. 9. 26. 17:04

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

 

1946번: 신입 사원

첫째 줄에는 테스트 케이스의 개수 T(1 ≤ T ≤ 20)가 주어진다. 각 테스트 케이스의 첫째 줄에 지원자의 숫자 N(1 ≤ N ≤ 100,000)이 주어진다. 둘째 줄부터 N개 줄에는 각각의 지원자의 서류심사 성

www.acmicpc.net

 

#문제

언제나 최고만을 지향하는 굴지의 대기업 진영 주식회사가 신규 사원 채용을 실시한다. 인재 선발 시험은 1차 서류심사와 2차 면접시험으로 이루어진다. 최고만을 지향한다는 기업의 이념에 따라 그들은 최고의 인재들만을 사원으로 선발하고 싶어 한다.

그래서 진영 주식회사는, 다른 모든 지원자와 비교했을 때 서류심사 성적과 면접시험 성적 중 적어도 하나가 다른 지원자보다 떨어지지 않는 자만 선발한다는 원칙을 세웠다. 즉, 어떤 지원자 A의 성적이 다른 어떤 지원자 B의 성적에 비해 서류 심사 결과와 면접 성적이 모두 떨어진다면 A는 결코 선발되지 않는다.

이러한 조건을 만족시키면서, 진영 주식회사가 이번 신규 사원 채용에서 선발할 수 있는 신입사원의 최대 인원수를 구하는 프로그램을 작성하시오.

 

 

#알고리즘

그리디 알고리즘

정렬

 

#풀이방법

처음에는 문제를 제대로 읽지 않아 성적을 점수로 착각해 정렬을 반대로 해버리는 만행을 저질렀다.

테케에서 나오는 점수는 우선순위일뿐 실제 점수가 아님을 유의하자....

 

문제를 다시 정리하자면,

어떤 지원자 A의 성적이 다른 어떤 지원자 B의 성적에 비해 서류 심사 결과와 면접 성적이 모두 떨어진다면 A는 결코 선발되지 않는다. 라는 말인데 이 말은 곧 2가지로 나뉠 수 있다.

 

지원자 A의 성적이 다른 지원자보다 서류 점수가 높거나 or 면접 성적이 높으면 뽑힐 수 있다.

 

일단 서류 심사를 기준으로 가장 좋은 성적을 받은 사람을 우선순위로 정렬한다.

 

테케를 예로 들면

3 2
1 4
4 1
2 3
5 5

 

 

5명의 후보자를 서류 성적 순위로 정렬하면

 

1 4 -- 1번 후보자

2 3 -- 2번 후보자

3 2 -- 3번 후보자

4 1 -- 4번 후보자

5 5 -- 5번 후보자

 

1번 후보자는 서류 점수가 다른 후보자들보다 높기 때문에 면접 점수가 어떻든 상관 없이 뽑힌다.

 

2번 후보자는 다른 후보자들보다 서류 점수가 높지만 1번 후보자보다 면접 순위에서 밀리면 안된다.

1번 후보자의 면접 순위와 비교하여 성적 순위가 더 높을 경우 선발되며 아닐 경우 탈락된다.

만약 선발 될 경우, 지금까지 2번 후보자의 면접 점수가 더 좋기 때문에 남은 후보자들의 면접 점수와의 비교대상으로 선정된다.

 

3번의 경우, 4번 5번보다 서류 점수가 더 좋기 때문에 4번 5번은 볼 필요도 없지만, 1번과 2번보다 서류점수가 떨어지기 때문에 1번과 2번의 면접 점수보다 높아야 선발 될 수 있다. 지금까지 제일 높은 면접 순위 maxScore와 비교하여 

면접 점수가 높을 경우 선발된 후 maxScore = 3번 후보자의 면접 순위 점수로 최신화되고, 아닌 경우 탈락하게 된다.

 

다른 후보자들도 똑같이 이런 방식으로 비교하여 선발 유/무를 결정한다.

 

 

 

#전체 코드

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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
import java.util.*;
//2t
 
public class Main {
 
    public static void main(String[] args) {
        
        Scanner sc = new Scanner(System.in);
        
        int T = sc.nextInt();
        int[] an = new int[T];
        
        for(int i=0; i<an.length; i++) {
            
            int num = sc.nextInt();//처음 후보자
            
            ArrayList<Cand> cand = new ArrayList<>();
            //후보 리스트 생성
            
            for(int j=0; j<num; j++) {
                
                int    doc = sc.nextInt();
                int interView = sc.nextInt();
                
                cand.add(new Cand(doc,interView));
                //리스트에 추가
            }
            
            Collections.sort(cand);
            //서류 점수가 가장 높은 우선순위를 가진 후보자를 기준으로 정렬
            
            int maxScore = cand.get(0).interView;
            //서류 기준으로 1순위인 후보의 면접 점수
            
            for(int j=1; j<cand.size(); j++) {
                
                if(maxScore < cand.get(j).interView) {
                    num--;//후보자--
                }//우선순위에서 밀리는 경우, 선발 x
                else {
                    maxScore = cand.get(j).interView;
                }//면접점수에서 이겼으므로 최신화
                
            }
            
            an[i] = num;
                
            
        }
        
        for(int i=0; i<an.length; i++)
            System.out.println(an[i]);
        
    }
 
}
 
class Cand implements Comparable<Cand>{
    
    int doc;
    int interView;
    
    Cand(int doc,int interView){
        
        this.doc = doc;
        this.interView = interView;
        
    }
    
    @Override
    public int compareTo(Cand o) {
        return this.doc-o.doc;
    }//서류 점수 기준으로 정렬
    //가장 좋은 서류 점수를 받은 인물이 1순위로 나오게 됨
    
}
cs