[백준/C++] 10773번: 제로

란지·2021년 9월 18일
0

백준

목록 보기
5/13

문제

나코더 기장 재민이는 동아리 회식을 준비하기 위해서 장부를 관리하는 중이다.

재현이는 재민이를 도와서 돈을 관리하는 중인데, 애석하게도 항상 정신없는 재현이는 돈을 실수로 잘못 부르는 사고를 치기 일쑤였다.

재현이는 잘못된 수를 부를 때마다 0을 외쳐서, 가장 최근에 재민이가 쓴 수를 지우게 시킨다.

재민이는 이렇게 모든 수를 받아 적은 후 그 수의 합을 알고 싶어 한다. 재민이를 도와주자!

문제보기

입력

첫 번째 줄에 정수 K가 주어진다. (1 ≤ K ≤ 100,000)

이후 K개의 줄에 정수가 1개씩 주어진다. 정수는 0에서 1,000,000 사이의 값을 가지며, 정수가 "0" 일 경우에는 가장 최근에 쓴 수를 지우고, 아닐 경우 해당 수를 쓴다.

정수가 "0"일 경우에 지울 수 있는 수가 있음을 보장할 수 있다.

출력

재민이가 최종적으로 적어 낸 수의 합을 출력한다. 최종적으로 적어낸 수의 합은 231-1보다 작거나 같은 정수이다.

예제

힌트

예제 2의 경우를 시뮬레이션 해보면,

[1][1,3]
[1,3,5][1,3,5,4]
[1,3,5] (0을 불렀기 때문에 최근의 수를 지운다)
[1,3] (0을 불렀기 때문에 그 다음 최근의 수를 지운다)
[1,3,7][1,3] (0을 불렀기 때문에 최근의 수를 지운다)
[1] (0을 불렀기 때문에 그 다음 최근의 수를 지운다)
[1,6]

합은 7이다.


아이디어

'가장 최근에 쓴 수를 지우게' 하는 문제이므로 후입선출(LIFO) 구조의 stack을 이용한다.
재민이가 잘못된 수를 부를 경우, 즉 재현이가 0을 외칠 경우에는 가장 최근에 재민이가 쓴 수를 지우도록 pop하고, 재민이가 올바른 수를 부를 경우 해당 값을 push한다.
K번의 입력이 끝나면 stack에 쌓여 있는 수를 하나씩 새로운 변수에 합하며 pop해준다.

코드

#include <iostream>
#include <stack>
using namespace std;
int main() {

	int K;
	cin >> K;
	int num;
	stack<int> stk;
	for(int i = 0; i < K; i++) {
		cin >> num;
		if (num == 0) {
			stk.pop();
		}
		else {
			stk.push(num);
		}
	}
	int sum = 0;
	for (int i = stk.size(); i > 0; i--) {
		sum = sum + stk.top();
		stk.pop();
	}
	cout << sum << endl;

	return 0;
}

시행착오

// 왜 i<=stk.size()만큼 반복하는지 모르겠음
for (int i = 0; i < stk.size(); i++) {
	sum = sum + stk.top();
	stk.pop();
}

처음에 for문의 조건을 다음과 같이 설정하였는데, 올바른 값이 출력되기 위해서는

i <= stk.size()

만큼 반복되어야 했다. 이 부분이 이해가 되지 않아 우선 while문을 사용해보았다.

// while문 사용
while (stk.empty() == 0) {
	sum = sum + stk.top();
	stk.pop();
}

이 경우 코드가 제대로 작동하였다. 이것을 토대로 for문의 조건을 stk.size()에서 작아지는 방식으로 변경하였다. 코드를 한줄 한줄 반복하며 따라가다보니 첫 번째와 같은 조건문이 필요하다는 것을 알게 되었다.

profile
콤퓨타공학과

0개의 댓글