C,C++

10773번 제로 C

코춘대길 2021. 6. 15. 23:56
728x90

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

 

10773번: 제로

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

www.acmicpc.net

이 문제에 들어가기 전 이 문제는 스택을 사용하는 자료형 문제로 스택은 간단히 말해 거대한 탑 모양의 메모리라고 생각하면 된다. push() 를 이용해 맨 밑에부터 자료를 넣어주고 pop() 을 이용해 탑의 꼭대기에서부터 값을 빼주는 가장 마지막에 넣은 정보를 가장 먼저 빼주는 자료구조입니다. 후입선출(後入先出/Last In First Out—LIFO)형 자료구조라고 합니다.

다시 돌아와서 문제의 핵심은 스택에 입력값을 넣고 만약 받은 값이 0 이라면 전의 값을 지우고 마지막에 스택 안에 남아있는 변수들의 합을 출력하면 됩니다. 

저는 두개의 코드를 이용하였는데 먼저 백준에서도 인정한 코드를 보여드리겠습니다.

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#define SIZE 100000  // c 언어는 스택을 바로바로 사용할 수 없기에 우리가 하나하나 다 만들어주어야 합니다.

int stack[SIZE]; // 스택 사이즈 지정
int top = -1; // 스택이 비어있을때 스택의 마지막 값을 -1 로 나타내줌

void push(int value) {
	if (top >= SIZE - 1)
		return;
		stack[++top] = value;      // 스택을 하나하나 만들어주어야하기 때문에 스택에 값을 넣는 push함수를 만들어줌
}

void pop() { 
	if (top<0)
		return;
	stack[top--] = 0; //위와 같은 이유로 스택에서 값을 빼주는 pop 함수
}



int main() {

	int num=0, value, num1;
	
	scanf("%d", &num1);

	for (int i = 1; i <= num1; i++) {
		
		scanf("%d", &value);

		if (value == 0)
			pop();
		else
			push(value);
		
	}

	for (int i = 0; i <= top; i++) {
		num += stack[i];
	}

	printf("%d", num);



	return 0;
}

 이 코드에서 보다 싶이 for 문으로 테스트 케이스 값 만큼 변수를 받아주고 if 문을 이용하여 0 일때 pop을 사용해서 스택안의 값을 지워줍니다. 그리고 마지막 포문을 이용해서 스택을 읽어주면서 i 번째의 스택의 값들을 확인하고 num 값에 넣어주어 출력합니다.

이 코드에서 알아야 할 점은 원래 c에서 는 스택이 가득차있을때와 스택이 비어있을때를 구해주는 함수가 필요한데 여기에서는 push 와 pop 함수 안에 if (top >= SIZE - 1) 과 top<0 을 이용하여 함수를 만들지 않고 표현해주었습니다.

짜잔!

이제 제가 처음에 두개의 코드를 이용해서 풀었다고 했는데 바로 보여드리겠습니다. 

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#define SIZE 100000

int stack[SIZE];
int top = -1;
int num;
int jar = 0;


int IsEmpty() {
	if (top < 0)
		return true;
	else
		return false;
}

int IsFull() {
    if (top >= SIZE - 1)
        return true;
    else
        return false;
}

void push(int numb) {
	if (!IsFull()) {
		top++;
		stack[top] = numb;
	}
		
}

char pop() {
	if (!IsEmpty()) {
		char temp = stack[top];
		top--;
		return temp;
	}
}

void result() {
	if (!IsEmpty()) {
		for (int i = 0; i <= top; i++) {
			jar += stack[i];
		}
	}
}


int main() {

	int num, numb,jar = 0;
	
	scanf("%d", &num);

	for (int i = 1; i <= num; i++) {
		
		scanf("%d", &numb);

		if (numb == 0)
			pop();
		else
			push(numb);
		
	}


	printf("%d", jar);



	return 0;
}

여기에서는 아까 말했다싶이 IsEmpty 와 IsFull 을 이용해서 가득찼을때와 비었을때를 계산하는 함수를 만들어 두었습니다. 여기선 result 함수를 이용해서 바로 스택 안의 값을 계산하여 jar 에 더한 값을 넣어주어 답을 출력합니다.

예제출력 1과 똑같이 출력이 나온다

위의 결과를 보듯이 두 코드 모두 예제와 결과값이 같습니다. 근데 놀랍게도 위의 코드는 정답인데 아래의 코드는 오답입니다. 이 이유는 모르겠습니당. 

사실 c++ 을 이용하면  include <stack> 을 이용해 함수를 만들 필요가 없습니다만,,,, C를 사랑합시다.