- 문제 출처 : https://www.acmicpc.net/problem/7785
1. 생각
직원이 출근을 했는데, 만약 또 같은 이름의 직원이 들어와도 해당 직원은 추가되면 안된다.
따라서 이 문제는 중복을 허용하지 않고, 정렬도 시켜주는 set 이 가장 적합한 문제라고 볼 수 있다.
그리하여, enter일 때는 insert()로 직원을 추가하고, leave일 때는 erase()를 활용해 명단에서 지운다.
이를 활용해서 문제를 풀어보도록 하자.
2. 난관 & 해결방법
int N;
std::string human, status;
std::set <std::string, std::greater<std::string>> st;
string으로 human과 status 를 받아준다. 이는 입력값으로 사용한다.
그리고, set 을 선언해주는데, 이번에는 내림차순으로 정렬해서 가지고 있어야하므로,
std::set <type, std::greater<type>> set_name 의 구조로 선언을 해줄 것이다.
(std::set <type> set_name 으로 선언하면 기본적으로 오름차순)
따라서 우리가 쓸 type은 std::string 이므로 해당 위치에 넣어주면 선언 완성.
std::cin >> N;
for (int i = 0; i < N; i ++){
std::cin >> human;
std::cin >> status;
if (status == "enter")
st.insert(human);
else if (status == "leave")
st.erase(human);
}
그리고 반복문을 돌리는데,
status에 따라 enter이면 insert, leave이면 erase 해준다.
erase()의 인자로 iterator를 사용할 수도 있지만, 자료 자체를 넣어도 해당 자료가 지워진다.
for (auto it = st.begin(); it != st.end(); it ++){
std::cout << *it << "\n";
}
그리고, 이제 회사 내부에 있는 직원들의 이름을 하나하나 출력해줘야 하는데,
우리는 이 set에 있는 begin iterator 부터 end iterator 까지 하나하나 접근해서 출력해줄 것이다.
그럼 여기서 iterator를 반복문의 인덱스로 사용하기 위해 작성해보면,
for (std::set <std::string, std::greater<std::string>>::iterator it = st.begin(); it != st.end(); it ++){
와 같이 for문을 작성하면 굉장히 길고 읽기가 어려운 반복문이 될 것이다.
이 때, 굉장히 편리한 'auto' 라는 키워드가 존재한다.
명시적으로 형을 지정하지 않아도 초기화 시 자동으로 형을 결정해주도록 해주는 키워드이다.
따라서 우리는 초기화를 set.begin()으로 넣어줄 것이기 때문에, auto는 begin의 형에 맞춰서 iterator로 결정될 것이다.
for (auto it = st.begin(); it != st.end(); it ++){
그 후, 포인터를 쓰듯이 iterator 앞에 * 을 붙혀주면 해당 값을 가져올 수 있다.
3. 코드 및 결론
[ 전체 코드 ]
#include <iostream>
#include <set>
int main(void){
int N;
std::string human, status;
std::set <std::string, std::greater<std::string>> st;
std::cin.tie(NULL);
std::ios::sync_with_stdio(false);
std::cin >> N;
for (int i = 0; i < N; i ++){
std::cin >> human;
std::cin >> status;
if (status == "enter")
st.insert(human);
else if (status == "leave")
st.erase(human);
}
for (auto it = st.begin(); it != st.end(); it ++){
std::cout << *it << "\n";
}
}
[ 결론 ]
문제가 굉장히 간단한 편이지만, 새로 써먹을만한 거리가 굉장히 많은 문제였다.
우선 set의 내림차순 초기화 방법과, iterator를 활용한 출력 방법, 또한 auto로 이를 간결하게 작성하는 법도 익혔다.
물론 이 auto는 자료형이 명확해야할 때는 사용을 자제해야하며, 남발하면 가독성과 코드 수정시 아려움이 생긴다.
자료구조 문제에서는 이런 활용법들을 항상 잘 익혀두고 추후에 활용할 수 있도록 다시 잘 읽어봐야겠다.
'프로그래밍 > Algorithm' 카테고리의 다른 글
[BOJ] 백준 10816번: 숫자 카드 2 (C++) (0) | 2025.04.28 |
---|---|
[BOJ] 백준 1620번: 나는야 포켓몬 마스터 이다솜 (C++) (0) | 2025.04.28 |
[BOJ] 백준 10815번: 숫자 카드 (C++) (0) | 2025.04.23 |
[BOJ] 백준 12789번: 도키도키 간식드리미 (C++) (0) | 2025.04.12 |
[BOJ] 백준 24511번: queuestack (C++) (0) | 2025.04.11 |