"펌프 잇 업" 의 개발사 "모른다미로" 에 개발자로 취직하게 된 아티초크는 펌프 잇 업의 후속작 개발을 맡게 되었다. 후속작에서 가장 크게 달라지는 점은, 발판의 개수가 N(1≤N≤250,000)개라는 점이다.
아티초크는 되도록 기존 코드를 그대로 가져다 쓰려고 했지만, 문제가 생겼다. 기존 코드는 발판 개수가 10개라는 전제하에 짜여 있던 터라, 그 코드에 바뀐 발판의 개수를 적용하기 만만치 않았다! 그래서 기존 코드를 수정할지, 아니면 아예 새로 짤지 고민하던 아티초크는 결국 다 엎고 처음부터 다시 짜기로 했다.
아티초크의 동업자인 당신은 먼저 판정, 콤보 시스템과 게임 결과 창을 화면에 표시하는 코드를 짜는 업무를 맡게 되었다. 해당 부분은 기본적으로 펌프 잇 업의 시스템을 그대로 따라가기로 했다.
게임 목표
펌프 잇 업의 목표는 기본적으로 "노트" 가 등장하는 시점에 맞게 발판을 밟는 것이다. 이때 노트와 관련된 용어의 정의는 다음과 같다.
판정
발판을 밟은 시점 근처에 해당 발판에 노트가 있었을 경우, "판정" 이 발생한다. 판정 시스템은 롱노트인지 일반노트인지 여부에 따라 다른데, 세부 사항과 관련 용어의 정의는 다음과 같다.
판정이란, 판정 기준과 플레이어가 발판을 밟은 시점이 얼마나 비슷한지 나타내는 것으로, 롱노트인지 일반노트인지 여부에 따라 판정 산정 방식이 다르다.
판정 기준 시점이란, 각 노트의 판정 계산에 있어 기준이 되는 시점으로, 판정 기준 시점과 판정 발생 시점의 차이로 판정을 계산한다.
일반노트의 판정 기준 시점은 노트의 등장 시점이며, PERFECT, GREAT, GOOD, BAD, MISS의 총 5가지 판정이 있다. 각각의 기준은 다음과 같다.
롱노트의 경우, 각 판정 기준 시점마다 발판을 밟고 있는 상태인 경우 PERFECT, 발판을 밟고 있지 않은 상태인 경우 MISS 판정을 받는다. 이때 판정 기준 시점은 다음 항목 중 하나 이상에 해당하는 경우를 의미한다.
롱노트의 판정 기준 시점과 해당 롱노트가 등장한 발판에서 발을 뗀 시점이 동일한 경우, 해당 시점에는 PERFECT 판정이 발생한 것으로 본다.
다중노트의 판정 기준 시점은 해당 시점에 등장하는 일반노트나 롱노트가 있는 경우 해당 노트의 등장 시점이며, 해당 시점에 끝나는 롱노트가 있는 경우 해당 노트가 끝나는 시점이 된다.
판정 우선순위는 PERFECT, GREAT, GOOD, BAD, MISS 순이다.
다중노트의 경우, 포함하는 노트 중 가장 우선순위가 낮은 판정을 받은 노트의 판정을 따른다.
판정의 발생
플레이어가 발판을 밟아 등장한 노트에 대한 판정이 부여되는 것을 "판정의 발생" 이라 한다. 이때 판정이 발생하는 시점도 해당 노트가 롱노트인지, 일반노트인지에 따라 달라진다.
콤보
플레이어가 연속하여 노트를 좋은 판정으로 처리하면 "콤보", 플레이어가 연속하여 노트를 놓치면 "미스콤보" 가 발생한다. 자세한 내용은 다음과 같다.
결과창
미스콤보가 51 이상이 되지 않는 한, 게임이 종료된 후 게임 결과를 출력한다. 자세한 내용은 다음과 같다.
당신은 노트들의 등장 시점과 플레이어가 발판을 밟기 시작한 시점, 발판을 뗀 시점이 모두 주어질 때, 상황에 맞는 판정, 콤보수, 게임 결과를 출력하는 프로그램을 구현하게 되었다. 뭘 하는진 모르겠지만 아무튼 바쁜 아티초크를 대신하여 구현해 보자.
첫 번째 줄에 발판의 개수 N(1≤N≤250,000)이 주어진다.
두 번째 줄에 판정 범위를 나타내는 t_p,t_gr,t_gd,t_b(1≤t_p<t_gr<t_gd<t_b≤109)가 주어진다.
다음 N개의 줄 중 i(1≤i≤N) 번째 줄의 첫 번째 수는 i번째 발판에 등장하는 일반노트의 개수 S_i를 의미한다. 그리고 다음 S_i개의 수는 노트가 등장하는 시점 s_1,s_2,⋯,s_S_i(1≤s_j<s_j+1≤109,1≤j<S_i)을 의미한다. 이때 S_i≥0이고, ∑_i=1NS_i≤250,000이다.
다음 N개의 줄 중 (1≤i≤N) 번째 줄의 첫 번째 수는 i번째 발판에 등장하는 롱노트의 개수 L_i를 의미한다. 그리고 다음 2L_i개의 수는 플레이어가 발판을 밟은 시점 l_1,l_2,⋯,l_2L_i(1≤l_j<l_j+1≤109,1≤j<2L_i)을 의미한다. 이때 L_i≥0이며, ∑_i=1NL_i≤250,000이고, 각 줄의 2L_i개의 수 중 홀수 번째로 등장하는 수는 롱노트가 시작하는 시점, 짝수 번째로 등장하는 수는 롱노트가 끝나는 시점을 의미한다. 롱노트가 시작하는 시점과 끝나는 시점 사이에 같은 발판에 일반노트가 등장하는 경우는 없다.
다음 N개의 줄 중 i(1≤i≤N)번째 줄의 첫 번째 수는 플레이어가 i번째 발판을 밟은 횟수 U_i를 의미한다. 그리고 다음 2U_i개의 수는 플레이어가 발판을 밟은 시점 u_1,u_2,⋯,u_2K_i(1≤u_j<u_j+1≤109,1≤j<2U_i)을 의미한다. 이때 U_i≥0이며, ∑_i=1NU_i≤500,000이고, 각 줄의 2U_i개의 수 중 홀수 번째로 등장하는 수는 발판을 밟기 시작한 시점, 짝수 번째로 등장하는 수는 발판을 뗀 시점을 의미한다.
노트 수(단, 다중노트는 하나의 노트로 취급한다)에 해당하는 줄 만큼, 해당 노트의 판정과, 필요하다면 현재 콤보 또는 미스콤보 수를 출력한다. 단, 도중에 미스콤보가 51 이상이 되는 경우, 이후 노트의 판정 및 결과창을 출력하지 않은 채로 프로그램을 종료한다.
한 번도 미스콤보가 51을 넘지 않은 채로 게임이 종료되었을 경우, 다음 6줄에는 결과창을 출력한다.
자세한 출력형식은 예체를 참고하도록 하자.