[실버1] 2841. 외계인의 기타 연주 (Java)
https://www.acmicpc.net/problem/2841
2841번: 외계인의 기타 연주
첫째 줄에 멜로디에 포함되어 있는 음의 수 N과 한 줄에 있는 프렛의 수 P가 주어진다. (1 ≤ N ≤ 500,000, 2 ≤ P ≤ 300,000) 다음 N개 줄에는 멜로디의 한 음을 나타내는 두 정수가 주어진다. 첫 번째
www.acmicpc.net
Fucking covid...
※ 문제를 요약하면 아래와 같습니다.
▶ 상근이의 상상의 친구 외계인은 손가락 수십억개를 가지구 기타를 원함
▶ 기타는 1번 ~ 6번까지 총 6개의 줄 존재, 각 줄은 P개의 프렛으로 구성
▶ 프렛의 번호는 1번 부터 P번까지 구성
▶ 멜로디는 음의 연속, 각 음은 줄에서 해당하는 프렛을 누르고 줄을 튕기면 연주
▶ 여러개의 프렛을 누르고 있다면 가장 높은 프렛의 음만 발생
▶ 손가락으로 프렛을 한 번 누르거나 뗐을 경우 손가락을 한 번 움직였다고 가정,
▶ 어떤 멜로디가 주어졌을 때, 손가락의 가장 적게 움직이는 회수를 구하는 프로그램 작성
▶ Input : 첫째 줄에 멜로디에 포함되어 있는 음의 수 N과 한 줄에 있는 프렛의 수 P 공백 구분 제공
: 다음 N개 줄에는 줄의 번호와 그 줄에서 눌러야 하는 프렛의 번호가 주어짐
: 반드시 주어진 순서대로만 연주
▶ Output : 멜로디를 연주하는데 필요한 최소 손가락 움직임 출력
◈ Input - 1
5 15
2 8
2 10
2 12
2 10
2 5
◈ Output - 1
7
◈ Input - 2
7 15
1 5
2 3
2 5
2 7
2 4
1 5
1 3
◈ Output - 2
9
◎ 코드 작성 전, 아래와 같이 솔루션을 정리하였습니다.
▶ Stack 자료형을 줄의 최대 갯수인 6개 만큼 선언
▶ 각 줄 별로 입력되는 프랫의 숫자를 Stack에 저장.
▶ 프랫의 숫자가 이전까지나온 숫자보다 높은 숫자가 나올 경우 추가로 숫자를 손가락으로 눌러야함
▶ 프랫의 숫자가 이전까지 나온 숫자보다 낮은 숫자가 나올 경우, 기존에 누르고 있던 높은 숫자의 프랫들은 손가락을 떼
▶ 손가락을 떼거나 누를 때 마다 카운트
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.Stack;
import java.util.StringTokenizer;
public class Main {
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
BufferedReader bReader = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bWriter = new BufferedWriter(new OutputStreamWriter(System.out));
StringTokenizer st = new StringTokenizer(bReader.readLine());
int N = Integer.parseInt(st.nextToken());
int P = Integer.parseInt(st.nextToken());
Stack<Integer>[] stPrats = new Stack[7];
for(int i = 0; i < 7; i++) {
stPrats[i] = new Stack<Integer>();
}
int nPratCount = 0;
for(int i = 0; i < N; i++) {
st = new StringTokenizer(bReader.readLine());
int nLine = Integer.parseInt(st.nextToken());
int nPrat = Integer.parseInt(st.nextToken());
// 새로운 프랫이 더 높을 때 까지 지워버려
while(!stPrats[nLine].empty() && nPrat < stPrats[nLine].peek()) {
nPratCount++;
stPrats[nLine].pop();
}
// 프랫이 같으면 걍 계속 누르고 있으면 돼
// 아닐경우엔 스택에 넣어주고 새로 프랫 눌러
if(stPrats[nLine].empty() || nPrat != stPrats[nLine].peek()) {
stPrats[nLine].push(nPrat);
nPratCount++;
}
}
bWriter.write(String.valueOf(nPratCount));
bWriter.flush();
bWriter.close();
}
}
코로나 때문에 꽤 오랜기간을 쉬어버렸네요 ㅠㅠ 이번 주말에 최대한 보충하도록 하겠습니다아!!
Good Luck! (피드백 감사합니다!)