[백준 1946번 C/C++] 신입 사원

 

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

 

1946번: 신입 사원

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

www.acmicpc.net


 

해결방법

 

탐욕 알고리즘 Greedy Algorithm

 

 


 

처음 시도한 코드 - 시간초과

 

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int t, n; // t: 테스트 케이스 개수, n: 지원자 수
int answer; // 선발할 수 있는 신입사원의 최대 인원수

struct Stat
{
	int doc;
	int interview;

	Stat(int a=0, int b=0) {
		doc = a;
		interview = b;
	}

	bool operator<(const Stat& a) const {
		return doc < a.doc;
	}
};

vector<Stat> v;

int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0); cout.tie(0);

	cin >> t;
	while(t--)
	{
		cin >> n;
		v.resize(n);
		for(int i = 0; i < n; i++){
			cin >> v[i].doc >> v[i].interview;
		}
		sort(v.begin(), v.end(), less<Stat>());
		for (int i = 0; i < n; i++) {
			cout << v[i].doc << " " << v[i].interview << "\n";
		}
		cout << "\n \n";

		answer = n;
		for(int i=0; i<n; i++){
			for(int j=0; j<i; j++)
			{
				if(v[j].doc < v[i].doc && v[j].interview < v[i].interview){
					answer--;
					break;
				}
			}
		}
		
		cout << answer << "\n";
		v.clear();
	}

	return 0;
}

 

 


 

정답 코드

 

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int t, n; // t: 테스트 케이스 개수, n: 지원자 수
int answer; // 선발할 수 있는 신입사원의 최대 인원수

struct Stat
{
	int doc; // 서류 점수
	int interview; // 면접 점수

	Stat(int a=0, int b=0) { // 생성자. 초기값은 0.
		doc = a;
		interview = b;
	}
	
	bool operator<(const Stat& a) const {
		return doc < a.doc;  // 서류 점수가 작은 순서로 정렬하기 위한 비교 연산자 오버로딩.
	}
};

vector<Stat> v; // 지원자들의 정보를 저장할 벡터

int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0); cout.tie(0);

	cin >> t;
	while(t--)
	{
		cin >> n;
		v.resize(n);
		for(int i = 0; i < n; i++){
			cin >> v[i].doc >> v[i].interview;
		}

		sort(v.begin(), v.end()); // 벡터 v를 서류 점수 기준으로 오름차순 정렬한다.

		answer = 1; // 첫 사람은 서류순위가 가장 낮으므로 무조건 등록
		int minInterviewRank = v[0].interview; // 현재까지 가장 낮은 면접 순위를 저장하는 변수. 첫 번째 사람의 면접 순위로 초기화한다
		
		for (int i = 0; i < n; i++) 
		{						
			// 만약 현재 (i번째)지원자의 면접 순위가 이전까지 본 최고 면접 순위(minInterviewRank)보다 낮다면 선발한다.
			// 새로 등장하는 (i번째)지원자의 서류점수는 이전에 등장한 지원자보다 같거나 크기 때문에 면접 순위가 더 작은 경우만 선발된다.
            if (v[i].interview < minInterviewRank){
				answer++; // 이 사람도 선발 가능하므로 answer 값을 증가
				minInterviewRank = v[i].interview; // 최고 면접 순위를 현재 지원자의 면접 순위로 갱신. 뒤에 등장하는 사람의 서류순위는 현재 사람과 같거나 더 크다. 따라서 뒤에 등장하는 사람의 인터뷰순위가 더 작은 경우에만 신입사원 채용 기준에 해당한다.
			}
		}

		cout << answer << "\n"; // 선발할 수 있는 최대 인원수를 출력
		v.clear(); // 다음 테스트 케이스를 위해 벡터 v를 초기화
	}

	return 0;
}