개발/자료구조, 알고리즘

[코딩 테스트] 소프티어(Softeer) 연습 문제 - 회의실 예약

growing-dev 2023. 2. 17. 23:05
반응형

코딩 테스트를 위한 소프티어(Softeer) 연습 문제 중 회의실 예약 문제를 풀어보고 리뷰해 본다.

 

연습 문제 - 회의실 예약

  • 난이도 : level 2
  • 정답률 : 63%

 

https://softeer.ai/practice/info.do?idx=1&eid=626 

 

Softeer

연습문제를 담을 Set을 선택해주세요. 취소 확인

softeer.ai

 

문제 해설

회의실 이름이 주어지고 각 회의실이 9시부터 18시까지 예약된 정보가 입력된다. 입력된 시간 정보를 바탕으로 비어 있는 회의실 정보를 출력하는 문제이다.

문제에서 고려해야 하는 포인트는 아래와 같다.

  • 입력 패턴을 이해하고 실수 없이 구현하기
  • 회의실 정보를 시간단위로 저장하기
  • 입력된 회의실 예약정보를 잘 처리하기
  • 출력 패턴을 실수 없이 구현하기

다른 level2 문제와는 다르게 다소 까다로웠다. 특히 출력을 표시하는데 생각보다 많은 시간이 들었다. 결론적으로 완전히 맞추지는 못했다. 코너 케이스를 고려해보아도 무엇이 잘못되었는지 알기 어려웠다. 아마도 단순한 포인트 일 것 같은데 시간이 좀 더 여유가 된다면 수정해서 최종적으로 맞추어야 할 것이다. 

 

입력

회의실의 이름은 영문 알파벳 소문자로만 이루어져 있으며 길이는 1 이상 10 이하이다.

주어지는 모든 시각은 9 이상 18 이하이다.

회의의 시작 시각은 회의의 종료 시각을 1시간 이상 앞선다.

입력형식

첫째 줄에 회의실의 수와 예약된 회의의 수를 나타내는 정수 N과 M이 공백을 사이에 두고 주어진다.

이어 N개의 줄에는 각 회의실의 이름이 주어진다.

이어 M개의 줄에는 각 회의가 배정된 회의실의 이름 r과 시작 시각 s, 그리고 종료 시각 t가 공백을 사이에 두고 주어진다.

출력형식
3 7
grandeur
avante
sonata
sonata 14 16
grandeur 11 12
avante 15 18
sonata 10 11
avante 9 12
grandeur 16 18
avante 12 15

 

출력

각 회의실에 대한 정보를 회의실 이름의 오름차순으로 출력한다.

각 회의실에 대한 정보는 다음과 같다.

첫째 줄에는 { Room 회의실이름: } (중괄호 제외)을 출력한다.

둘째 줄에는 예약가능 시간을 출력한다.

- 예약 가능한 시간대의 개수를 n이라고 할 때, { n available: } (중괄호 제외)을 출력하고, 뒤따른 n개의 줄에 예약 가능한 시간대를 { 09-18 } (하이픈 한 개, 중괄호 제외) 형태로 출력해야 한다. 한 자리 수의 경우 앞에 0을 붙여 두 자리 수로 만들어야 함에 유의하라.

- 예약 가능한 시간이 없다면, Not available을 출력한다.

각 회의실에 대한 정보 사이에는 ----- (하이픈 다섯 개)로 구분선이 출력되어야 한다.

 

Room avante:
Not available
-----
Room grandeur:
2 available:
09-11
12-16
-----
Room sonata:
3 available:
09-10
11-14
16-18
 

코드

#include<iostream>
#include<vector>
#include<map>
#include<algorithm>

using namespace std;
// N개
// 9시~18시
// 회의 : 회의실, 시작, 종료 (시간 단위)
// 이미 예약된 M 개의 회의 정보에서 비어있는 시간대를 정리해서 출력
int main(int argc, char** argv)
{
// N 50, M 100
	vector<pair<string,int>> v;

	int N, M;
	string name;
	int start,end;
	cin >> N >> M;
	for (int i = 0; i < N; i++) {
		cin >> name;
		v.push_back(make_pair(name,0));
	}
	for (int i = 0; i < M; i++) {
		cin >> name >> start >> end;
		//find meeting room and allocate time
		for (auto it =v.begin(); it != v.end();it++) {
			if (it->first == name) {
				for (int i = start-9; i <= end-9; i++) {
					it->second |= 1 << i;
				}
			}
		}
	}
	//sort meeting room by name
	sort(v.begin(),v.end());
	
	//print empty time
	for (int i = 0; i < N; i++) {
		cout << "Room " << v[i].first <<":" << endl;
		int count =0;

		// find start and end pos
		int start = 0;
		int end = 9;
		vector<pair<int,int>> res;
		for (int j = 0; j <= 9;j++) {
			int pos = 1 << j;
			if ((v[i].second & pos) != pos) {
				start = j;
				for (int k = j; k <= 9; k++) {
					int pos2 = 1 << k;
					if ((v[i].second & pos2) == pos2) {
						end = k; break;
					}
				}
				if (start > end) end = 9;
				if (start != 0) start--;
				 
				res.push_back(make_pair(start+9, end+9));
				j = end;
				if (end == 9) break;
			}
		}
		size_t size = res.size();
		if (size == 0) {
			cout << "Not available" << endl;
		}
		else {
			cout << res.size() << " available:" << endl;
			for (auto it = res.begin(); it != res.end(); it++) {
				if (it->first == 9) cout << "0";
				cout << it->first << "-" << it->second << endl;
			}
		}
		if (i != N-1)
			cout << "-----" << endl;
	}

	return 0;
}

 

결론

앞서 말했듯 최종적으로 답이 맞지 않았다. 여러 케이스들을 만들어서 입력해 보았지만 문제가 없었다. 아마도 로직의 문제 보다는 출력표시 형식의 문제일 확률이 높아 보였다. 물론 로직의 문제일 가능성도 없지 않았다. 나는 비트의 조합으로 가능한 메모리와 시간을 줄이려고 처음부터 접근했는데, 각각의 회의 시간을 벡터나 배열로 다 만드는 식으로 조금 단순하게 먼저 접근했다면 로직의 오류를 줄일 수 있을 것 같다.

반응형