쌓고 쌓다

[백준] 외계인의 기타 연주 2841번 C++풀이 본문

알고리즘/백준

[백준] 외계인의 기타 연주 2841번 C++풀이

승민아 2022. 3. 23. 21:12

https://www.acmicpc.net/problem/2841

 

2841번: 외계인의 기타 연주

첫째 줄에 멜로디에 포함되어 있는 음의 수 N과 한 줄에 있는 프렛의 수 P가 주어진다. (N ≤ 500,000, 2 ≤ P ≤ 300,000) 다음 N개 줄에는 멜로디의 한 음을 나타내는 두 정수가 주어진다. 첫 번째 정수

www.acmicpc.net

 

전체 코드

#include <iostream>
#include <stack>
using namespace std;
int N, P;
int res = 0;
stack<int> s[7];
int main(void) 
{
	cin >> N >> P;
	int a, b;
	for (int i = 0; i < N;i++)
	{
		cin >> a >> b;
		if (s[a].empty()) // 비었으면 그냥 누르기
		{
			s[a].push(b);
			res++;
		}
		else // 이미 뭔가 있을경우
		{
			if(s[a].top()<b) // 입력이 더 큰 프렛 번호면 걍 누르면 됨
			{
				res++;
				s[a].push(b);
			}
			else
			{ // 입력이 더 작은수면 입력 수보다 작은수가 나올때까지 pop
				while (!s[a].empty()&&s[a].top() > b)
				{
					s[a].pop();
					res++;
				}
				//그리고 눌러주는데 누를 프렛과 현재 손가락이 올라가있는 프렛이 같을수도 있음
				if (!s[a].empty() && s[a].top() == b)
					continue; // 그땐 그냥 손가락 움직일 필요가 없음
				//다르면 손가락을 움직여 눌려줘야함
				s[a].push(b);
				res++;

			}
		}
	}
	cout << res;
}

 

6개의 줄이 있기에 각 줄에 해당하는 스택 6개를 사용해야합니다.

내가 누를 프렛이 현재 눌려진 프렛보다 클경우 그냥 누르면 됩니다.

왜냐하면 굳이 낮은 프렛을 때나마나 큰 프렛을 치는데 영향이 안가기 때문입니다.

하지만, 내가 누를 프렛이 현재 눌려진 프렛보다 낮을 경우

아무리 낮은 프렛을 눌려 쳐도 높은 프렛이 눌려져있어 음이 안나옵니다.

 

+ 내가 누를 프렛이 이미 눌려져 있을경우 손가락을 움직일 필요가 없습니다.

누를 프렛과 이미 눌려진 프렛을 비교하는 if문이 코드에 있습니다.

Comments