코테/항해99

[99클럽 코테 스터디 8일차 TIL] #해시4

쪼성윤 2024. 11. 4. 22:44

새로운 한 주가 시작되었어요. 점점 실력이 늘고 있는 게 느껴져서 기분이 좋네요. 8일 차 문제도 파이팅 넘치게 풀어보도록 하겠습니다!

 

문제 설명


 

주의 개수인 n기 입력이 되고 주마다의 근무표가 일일이 주어집니다.

이 근무표를 바탕으로 각 사람마다 근무시간을 계산해서 각 인원의 근무시간이 12시간 이하인지를 구별해내는 코드를 작성하는 문제입니다.

 

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

 

 

 

생각 흐름


오늘의 문제는 신기하게도 이해가 잘 되지 않는 문제였어요. 문제만 10분넘게 본 것 같은데..

입력되는 값들이 워낙 많다보니 이것들이 무엇을 의미하는지를 알아내기 위해서 시간을 좀 많이 들였습니다.

 

결국은 단순한 것을 묻고 있는 문제였지만 너무 많은 정보량에 또 당황해 버렸어요.

 

그래도 천천히 반복문을 작성해 보았습니다. 우선, 문제에서 주어진 대로 주의 개수인 n을 받아오고 각 주가 4개의 줄로 표현된다는 점, 주는 7일로 구성된다는 점을 가지고 3중 for 반복문을 작성하여 가닥을 잡아주었습니다.

 

그렇게 하고 각 인원들의 이름마다 근무시간을 저장해 줄 map 자료구조를 선언하고 이를 하나씩 받아주는 구문을 작성하였습니다.

 

여기서 또 문제가 웃겼던 게, 근무타임마다 근무시간이 제각각이라는 점에서 hours [4] 배열을 따로 선언해 주어 이에 맞게 map에 저장을 해주었어요.

 

그리고 마지막 문제의 키포인트, 각인원의 근무시간이 12시간 이하로 차이가 나는지를 알아보기 위한 조건문을 작성해 보았습니다.

 

여기서 시간을 좀 지체를 했는데..

 

수학적으로 접근했을 때, 각인원 근무시간 최댓값과 최솟값의 차가 12보다 작은지 큰지만 확인하면 조건 확인이 가능하다고 생각해서 map 자료구조의 value값 뺄셈을 어떻게 처리하지.. 고민을 하다가

 

iterator를 선언해 버리자는 결론을 냈어요. key와 value에 접근해서 뺄셈을 하는 방식이 처리하기가 어렵더라고요. 뭐 방법이 있을 것 같은데 도저히 모르겠어서 다른 방법으로 풀어보았습니다.

 

저번시간에 공부한 삼중 조건문도 사용해서 마무리해 보았습니다.

#include <bits/stdc++.h>
using namespace std;

int main () {
    ios_base::sync_with_stdio();
    cin.tie(); cout.tie();

    int n; // 주의 개수 n
    string temp; // 들어오는 문자열
    unordered_map<string, int> work;
    int hours[4] = {4,6,4,10}; // 근무시간이 저장되있는 int 배열

    cin >> n;

    for (int i = 0; i < n; i++) {
        for (int j = 0; j < 4; j++) { // 4주마다 반복 
            for (int k = 0; k < 7; k++) { // 7개의 요일 반복
                cin >> temp;

                if (temp == "-") {
                    continue;
                }
                work[temp] += hours[j];
            }
        }
    }
    
    int maxtime = -1; 
    int mintime = 9999999;
    for (auto iter = work.begin(); iter != work.end(); iter++) {
        maxtime = maxtime < iter->second ? iter->second : maxtime;
        mintime = mintime > iter->second ? iter->second : mintime;
    }

    if (maxtime - mintime <= 12) {
        cout << "Yes" << "\n";
    }

    else {
        cout << "No" << "\n";
    }

    return 0;
}

 

 

공부한 내용 정리


오늘 문제를 풀면서 아직 map 자료구조에서 key, value를 다루는 게 아직 어색하다고 느껴서

관련 개념 중 map iterator에 대해 다시 공부해 보기로 하였습니다.

 

1. map iterator (반복자)

hash를 이용한 unordered_map의 경우, hash를 사용하기 때문에 순서를 정할 수 없어서 iterator에 대한 사용을 볼 수 없었는데,

 

이진탐색트리를 이용한 map의 경우는 key-value 쌍에서 key 값에 대해서 순서를 가지면서 자료들이 담기기 때문에 이에 대해서 iterator을 사용하여서 순서를 따라가면서 원소에 접근할 수 있고,

 

이때에 iterator를 사용할 때에 -> (arrow operator, 화살표 연산자)를 사용하여서 각각의 pair의 first와 second에 접근할 수 있다.

 

for (auto iter = work.begin(); iter != work.end(); iter++) {
        maxtime = maxtime < iter->second ? iter->second : maxtime;
        mintime = mintime > iter->second ? iter->second : mintime;
    }

 

 

오늘 작성한 코드에서와 같이 iterator it을 선언해서 이를 요소들의 순서대로 접근해서 사용하였다.

 

다음에도 iter->first, iter->second 이런 식으로 접근해서 문제 풀면 될 것 같다.