[백준] 19583 - 싸이버개강총회
1. 문제
2. 개요
회전초밥 가게에서 두가지 이벤트를 동시에 진행한다.
- 원래 회전 초밥은 손님이 마음대로 초밥을 고르고, 먹은 초밥만큼 식대를 계산하지만, 벨트의 임의의 한 위치부터 k개의 접시를 연속해서 먹을 경우 할인된 정액 가격으로 제공한다.
- 각 고객에게 초밥의 종류 하나가 쓰인 쿠폰을 발행하고, 1번 행사에 참가할 경우 이 쿠폰에 적혀진 종류의 초밥 하나를 추가로 무료로 제공한다. 만약 이 번호에 적혀진 초밥이 현재 벨트 위에 없을 경우, 요리사가 새로 만들어 손님에게 제공한다.
회전벨트의 상태, 초밥의 가짓수, 연속으로 먹을 접시의 개수, 쿠폰으로 받은 초밥의 종류가 각각 주어졌을 때, 손님이 먹을 수 있는 초밥의 최대 종류를 구하는 문제.
3. 풀이 및 코드
3-1. 풀이
싸이버개강총회를 진행하려고 한다. 이 총회의 출석은 다음과 같은 방식을 통해 확인하려고 한다.
- 개강총회를 시작하기 전에, 학회원의 입장 확인 여부를 확인한다. 학회원의 입장 여부는 개강총회가 시작한 시간 이전에 대화를 한 적이 있는 학회원의 닉네임을 보고 체크한다. 개강총회를 시작하자마자 채팅 기록을 남긴 학회원도 제 시간에 입장이 확인된 것으로 간주한다.
- 개강총회를 끝내고 나서, 스트리밍을 끝낼 때까지 학회원의 퇴장 확인 여부를 확인한다. 학회원의 퇴장 여부는 개강총회가 끝나고 스트리밍이 끝날 때까지 대화를 한 적이 있는 학회원의 닉네임을 보고 체크한다. 개강총회가 끝나자마자 채팅 기록을 남겼거나, 개강총회 스트리밍이 끝나자마자 채팅 기록을 남긴 학회원도 제 시간에 퇴장이 확인된 것으로 간주한다.
이 때, 출석이 확인된 인원수를 구하는 문제.
주어지는 시간이 모두 같은 날의 00:00 ~ 24:00 이므로 이를 정수화하여 사용할 수 있다.
만약 총회 시작 전의 기록이라면 입장확인 집합에 기록하고, 총회 종료 ~ 스트리밍 종료 사이의 기록이라면 퇴장확인 집합에 기록한다.
입장확인 기록과 퇴장확인 기록의 교집합이 온전한 출석체크 기록이 되므로 이 교집합의 크기를 출력한다.
3-2. Python
import sys
S, E, Q = sys.stdin.readline().split()
S = ''.join(S.split(':'))
E = ''.join(E.split(':'))
Q = ''.join(Q.split(':'))
S, E, Q = int(S), int(E), int(Q)
enterchk = set()
exitchk = set()
while True:
info = list(sys.stdin.readline().split())
if not info:
break
infotime = ''.join(info[0].split(':'))
infotime = int(infotime)
if infotime <= S:
enterchk.add(info[1])
elif E <= infotime <= Q:
exitchk.add(info[1])
chked = enterchk.intersection(exitchk)
print(len(chked))
3-3. C#
namespace boj_19583
{
internal class Program
{
static void Main(string[] args)
{
string[] input = Console.ReadLine().Split();
int S = int.Parse(string.Join("", input[0].Split(":")));
int E = int.Parse(string.Join("", input[1].Split(":")));
int Q = int.Parse(string.Join("", input[2].Split(":")));
HashSet<string> enterChk = new();
HashSet<string> exitChk = new();
while (true)
{
string info = Console.ReadLine();
if (info == "" || info == null)
break;
string[] infos = info.Split();
int infoTime = int.Parse(string.Join("", infos[0].Split(":")));
if (infoTime <= S)
enterChk.Add(infos[1]);
else if (infoTime >= E && infoTime <= Q)
exitChk.Add(infos[1]);
}
List<string> intersection = enterChk.Intersect(exitChk).ToList();
Console.WriteLine(intersection.Count);
}
}
}
Comments