https://www.acmicpc.net/problem/19583
#include <iostream>
#include <map>
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
string s, e, q;
int ans = 0;
map<string, int> att;
cin >> s >> e >> q;
string t, nick;
while (cin >> t >> nick) {
if(att[nick]==1 && t >= e && t <= q) {
att[nick] = 2;
ans++;
}
else if (t <= s) {
att[nick] = 1;
}
}
cout << ans;
return 0;
}
1. 문제
개강총회를 시작한 시간 S, 개강총회를 끝낸 시간 E, 개강총회 스트리밍을 끝낸 시간 Q가 주어진다. 이후 스트리밍 영상의 채팅 기록과 해당 채팅을 작성한사람 닉네임이 주어진다. 이 사람들의 출석 여부를 확인하기 위해 다음과 같은 규칙을 정했다
- 개강 총회를 시작하기 전 사람들의 입장 여부를 확인한다. 시작하자마자 채팅을 남겨도 인정한다.
- 개강 총회가 끝나고, 스트리밍이 끝날 때까지 퇴장 여부를 확인한다. 개강총회가 끝나자마자, 혹은 스트리밍이 끝나자마자 채팅을 남겨도 인정한다
이 때, 입장과 퇴장이 모두 확인된 사람의 수를 구해야 한다.
2. 풀이
입력 개수가 10만개까지이므로 배열에 대충 집어넣고 입력이 들어올 때 마다 그 여부를 확인하면 시간초과가 날 수 있다. 따라서 map을 사용하여 풀었다.
while (cin >> t >> nick) {
if(att[nick]==1 && t >= e && t <= q) {
att[nick] = 2;
ans++;
}
else if (t <= s) {
att[nick] = 1;
}
}
입력의 개수가 주어지지 않으므로 위와 같이 입력받는다. 입장이 확인되면 map에 {nick, 1}을 추가한다. 입장이 확인된 상태에서 개강총회 종료와 스트리밍 종료 사이에 채팅을 쳤다면 {nick, 2}로 수정하고, ans 변수를 더해준다. 이를 출력하면 정답을 구할 수 있다.
3. 시행착오
while (cin >> t >> nick) {
if(att[nick] && t >= e && t <= q) {
att[nick];
ans++;
}
else if (t <= s) {
att[nick] = true;
}
}
처음에 이렇게 적어 제출했다가 틀렸다. 이는 같은 사람이 채팅을 여러 번 칠 수 있기 때문이다. 입장한 사람은 map에서 att[nick]=true에서 변하지 않으므로 개강총회가 끝나고 스트리밍이 끝날 때 까지 채팅을 여러 번 친다면 ans가 그 수만큼 늘어난다. 이 문제는 사람의 수를 구하는 문제이기 때문에 오답 처리가 되는 것이다.
'Coding Test' 카테고리의 다른 글
백준 10775 공항 (1) | 2024.06.24 |
---|---|
백준 1918 후위 표기식 (0) | 2024.06.22 |
백준 1927 최소 힙 (0) | 2024.06.20 |
백준 5430 AC (0) | 2024.06.19 |
백준 5397 키로거 (0) | 2024.06.18 |