백준 1931 - 회의실 배정
1 minute read
문제링크
오답을 이끌었던 문제 접근1 (시간초과)
- 각 회의를 시작시간을 기준으로 오름차순 정렬
- 앞에서부터 회의노드를 방문하면서 현재 회의노드의 끝나는 시간 이후에 진행하는 회의노드를 방문한다.
- 더 이상 방문할 수 있는 회의노드가 없는 경우 백트래킹을 통해 돌아온 후 다시 탐색한다.
잘못된 접근이었던 이유
- 백트래킹을 통해 접근하는 방법은 문제를 너무 어렵게 해석했던 것으로 판단된다.
- DFS의 재귀 구현에도 어려움을 겪으면서 의도했던 대로 동작하는 코드를 작성하지 못했다.
오답을 이끌었던 문제 접근2 (시간초과)
- 반복문을 통해 접근하였으나, 반복문 중첩을 통해 모든 경우의 수를 확인하려고 했던 점이 원인이었다.
- 최대 십만(100,000)개의 회의가 존재할 수 있는데 반복문 중첩은 최대 백만번의 비교연산과 대입연산이 필요하기 때문에 시간초과에 걸렸다.
문제 접근 방향 (Solution)
- 시작하는 시간이 빨라도 늦게 끝나면 최대 회의 수를 맞출 수 없으므로, 회의의 종료시간이 중요한 요소이다.
- 종료 시점에 대해서 오름차순 정렬
- 반복문을 통해 탐색하면서 if 탐색대상의 end_time <= 비교대상의 start_time then, end_time 갱신
- count += 1
- 배열의 끝에 도달할 때까지 2,3번 반복
런타임에러(Segfault)
- 할당되지 않은 메모리에 접근하려고 할 때 발생한다.
- sort 함수에서 cmp가 일관되지 않을 때 발생할 수 있다고 한다.
구현 결과
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
typedef struct _meet
{
int start;
int end;
} Meet;
int N;
vector<Meet> v;
bool cmp(Meet m1, Meet m2)
{
if (m1.end != m2.end)
return m1.end < m2.end;
else if (m1.end == m2.end)
return m1.start < m2.start;
}
int proc()
{
int count = 1; // 처음에 회의는 하나
int end_time = v[0].end;
for (int i = 1; i < v.size(); i++)
{
if (end_time <= v[i].start)
{
end_time = v[i].end;
count++;
}
}
return count;
}
int main()
{
cin.tie(NULL);
ios_base::sync_with_stdio(false);
cin >> N;
Meet tmp;
for (int i = 0; i < N; i++)
{
cin >> tmp.start >> tmp.end;
v.push_back(tmp);
}
sort(v.begin(), v.end(), cmp); // N개의 회의
int ans = proc();
cout << ans << endl;
return 0;
}
Leave a comment