📕문제
보영이는 알고리즘 동아리 HI-ARC를 운영하고 있다.
보영이와 운영진 일동은 20년도에 입학하는 신입생들을 맞이하기 위해 열심히 준비를 해왔으나, 전염병의 유행이 악화된 나머지 정부에서는 “사회적 거리두기”를 선언했고 그에 따라 학교에서는 교내 모든 동아리에 오프라인 모임을 자제하라는 공지를 하기에 이르렀다. 오프라인에서 모임을 자제하라는 권고가 나온 어려운 상황에도 불구하고, 보영이는 기지를 발휘하여 개강총회를 미튜브 스트리밍으로 대체하는 결정을 하게 된다.
하지만, 미튜브 스트리밍으로 개강총회를 하게 될 경우, 아래와 같은 문제가 있었다.
- 누가 개강총회에 왔는지 알 수 없다.
- 누가 개강총회 자리에 끝까지 남아있었는지 알 수 없다.
- 어떤 사람이 개강총회 스트리밍을 단순히 틀어놓기만 했는지 알 수 없다.
이런 문제를 해결하기 위해서, 다음과 같이 출석부를 관리하기로 결심했다.
- 개강총회를 시작하기 전에, 학회원의 입장 확인 여부를 확인한다. 학회원의 입장 여부는 개강총회가 시작한 시간 이전에 대화를 한 적이 있는 학회원의 닉네임을 보고 체크한다. 개강총회를 시작하자마자 채팅 기록을 남긴 학회원도 제 시간에 입장이 확인된 것으로 간주한다.
- 개강총회를 끝내고 나서, 스트리밍을 끝낼 때까지 학회원의 퇴장 확인 여부를 확인한다. 학회원의 퇴장 여부는 개강총회가 끝나고 스트리밍이 끝날 때까지 대화를 한 적이 있는 학회원의 닉네임을 보고 체크한다. 개강총회가 끝나자마자 채팅 기록을 남겼거나, 개강총회 스트리밍이 끝나자마자 채팅 기록을 남긴 학회원도 제 시간에 퇴장이 확인된 것으로 간주한다.
단, 00:00부터는 개강총회를 시작하기 전의 대기 시간이며, 개강총회 스트리밍 끝난 시간 이후로 남겨져 있는 채팅 기록은 다른 스트리밍 영상의 채팅 기록으로 간주한다.
이때, 입장부터 퇴장까지 모두 확인된 학회원은 전부 몇 명인가?
📕입력
첫 번째 줄에는 개강총회를 시작한 시간 S, 개강총회를 끝낸 시간 E, 개강총회 스트리밍을 끝낸 시간 Q가 주어진다. (00:00 ≤ S < E < Q ≤ 23:59)
각 시간은 HH:MM의 형식으로 주어진다.
두 번째 줄부터는 HI-ARC에서 방송하는 스트리밍 영상의 채팅 기록들이 시간순으로 주어지는데, (시간) (학회원 닉네임)의 형태로 주어진다. 학회원의 닉네임은 알파벳 대소문자와 숫자, 그리고 특수 기호(., _, -)로만 구성된 문자열이며 최대 20글자이다.
모든 채팅 기록은 개강총회가 일어난 날에 발생한 채팅 기록이다. 즉 00:00~23:59의 시간만 주어진다. 채팅 기록은 10만 줄을 넘지 않는다.
🔎문제해석
문제가 굉장히 길다;; 당황스러웠다. 차근차근 읽어 보니 문제에서 요구하는 바가 보였다.
개강총회 시작시간까지 스트리밍에 들어와서 채팅을 쳐야 한다. [1번 조건을 만족해야 함]
그 이후 개강총회 종료시간~개강총회 스트리밍 종료시간까지 채팅을 쳐야 한다. [2,3조 건을 만족해야 함]
나는 map을 사용해서 문제를 풀었다.
그리고 입력의 개수가 명시되어있지 않기 때문에 입력이 공백일 때 break 해줬다.
⚡구현
- 입력이 00:00 형태로 주어지기 때문에 해당 문자열에 시간을 분단위로 int 변수에 넣어줬다.
- 시간과 이름을 입력받는다.
- 만약 공백이면 입력이 끝인 거임.
- 입력받은 시간을 분단위로 바꿔서 int변수에 저장한다.
- 만약 시간이 개강총회 스트림이 시간보다 크다면 밑에 본문을 실행할 필요가 없다.
- 만약 채팅을 친 시간이 개강총회 시작 전이라면 조건 1에 부합하므로 map에 넣어준다.
- 그리고 다시 채팅을 친 시간이 개강총회 종료시간(e)~개강총회 스트리밍 종료시간(q) 사이에 있다면 cnt를 늘려주고 map에다가 해당 이름을 지웠다.
📃코드
/*
백준 19583 실버2 싸이버개강총회
*/
#include <iostream>
#include <vector>
#include <algorithm>
#include <map>
#include <sstream>
using namespace std;
string S, E, Q;
map<string, int> m;
int main()
{
ios_base::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
cin >> S >> E >> Q;
int s = S[0] * 600 + S[1] * 60 + S[3] * 10 + S[4];
int e = E[0] * 600 + E[1] * 60 + E[3] * 10 + E[4];
int q = Q[0] * 600 + Q[1] * 60 + Q[3] * 10 + Q[4];
int cnt = 0;
while (1)
{
string Time, name;
cin >> Time >> name;
if (Time == "" && name == "")
break;
int t;
t = Time[0] * 600 + Time[1] * 60 + Time[3] * 10 + Time[4];
if (t > q)
{
continue;
}
if (t <= s) //제시간에 입장.
{
m.insert(make_pair(name, 1));
}
//여기서 개강총회가 시작하고~ 스트리밍이 끝나기 전까지의 채팅 기록이 있어야함.
else if (t >= e && t <= q)
{
// map에 들어있고, 채팅이 있어야함.
if (m.find(name) != m.end()) // map에 이름이 있고, 시간이 개강총회시작시간 ~ 개강총회스트리밍끝나는 시간 안에 채팅을 쳐야함.
{
cnt++;
//증가시켜줫으니 map에서 지워야함.
m.erase(m.find(name));
}
}
}
cout << cnt;
}
✔느낀 점
- 난이도에 딱 맞는 문제였다.
- 처음에 문제 이해가 안돼서 굉장히 애를 먹었다. 그리고 입력이 멈췄을 때 멈추는 조건을 다른 방식으로 주고 싶었는데 생각이 안 났다.
- 나는 map을 썼는데 map을 굳이 안 써도 풀렸을 문제였다. [set을 써야 하는 게 맞는 듯?]
'CodingTest > Baekjoon' 카테고리의 다른 글
[백준 5430] AC(C++) (2) | 2022.08.21 |
---|---|
[백준 2002] 추월(C++) (0) | 2022.08.20 |
[백준 1753] 최단경로(C++) (0) | 2022.08.16 |
[백준 17396] 백도어(C++) (0) | 2022.08.15 |
[백준 1916] 최소비용 구하기(C++) (0) | 2022.08.13 |