※ 백준 (Baekjoon)/[Java] 문제 풀이 ( Solve the problems)

[실버1] 2841. 외계인의 기타 연주 (Java)

J 크 2023. 9. 6. 17:38
728x90
반응형

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! (피드백 감사합니다!)