본문 바로가기
Algorithm(코딩테스트)/코딩테스트 문제 풀이 | 해시,집합(Map,Set)

[백준] 16165번 걸그룹 마스터 준석이 <C++>

by 카랑현석 2024. 2. 3.

문제



문제 분석

unordered_map(해시)을 통해 key와 value 값을 양방향으로 검사하는 테크닉을 익히는 문제이다.

 

key 값을 통해 value 값을 찾는 것은 find 함수로 쉽다.

value 값을 통해 key 값을 찾으려면 iterator을 순회하면서 찾아야 한다. 대신 시간 제한이 빡빡한 경우 배열에 key 값을 저장해두고 배열의 인덱스로 접근하는 방법도 있지만 이 문제의 경우 N과 M의 범위가 100으로 작고 시간 제한도 2초이므로 iterator로 순회해도 된다.

 

정답 코드

문제 요구사항을 그대로 구현하면 된다.

#include <iostream>
#include <unordered_map>
#include <algorithm>
#include <string>
using namespace std;

unordered_map<string, string> um; // (멤버 이름, 팀 이름)

int main(void) {
	ios_base::sync_with_stdio(false); cin.tie(nullptr); // 고속 입출력

	int N, M;
	cin >> N >> M;

	// 정보 입력
	for (int i = 0; i < N; i++) {
		string group_name;
		int member_cnt;
		string talent_name;

		cin >> group_name;
		cin >> member_cnt;
		for (int j = 0; j < member_cnt; j++) {
			cin >> talent_name;
			um.insert(make_pair(talent_name, group_name));
		}
	}

	// 퀴즈 풀기
	for (int i = 0; i < M; i++) {
		int flag; 
		string quiz; // 변환해야 하는 문제
		
		cin >> quiz;
		cin >> flag;

		// 0 : 팀 이름 -> 멤버 이름(오름차순) 
		if (flag == 0) {
			vector<string> v_ans;
			unordered_map<string, string>::iterator iter;
			for (iter = um.begin(); iter != um.end(); iter++) {
				if (iter->second == quiz) { // 찾고자 하는 팀 이름의 멤버들을 v_ans 가변배열에 넣는다.
					v_ans.push_back(iter->first);
				}
			}
			// 멤버 이름을 오름차순으로 정렬한다.
			sort(v_ans.begin(), v_ans.end());
			// 해당하는 멤버 이름을 모두 출력한다.
			for (int j = 0; j < v_ans.size(); j++) {
				cout << v_ans[j] << "\n";
			}
		}

		// 1 : 멤버 이름 -> 팀 이름
		if (flag == 1) {
			auto iter = um.find(quiz);
			cout << iter->second << "\n";
		}
	}

	return 0;
}



교훈점

map 자료구조에서 데이터에 접근할 때 key와 value 값을 양방향을 자유자재로 접근하고 뽑아낼 수 있는 테크닉을 얻었다.