🌞Algorithm/🔥Baekjoon

[Baekjoon] 3425_고스택

뿌야._. 2023. 6. 27. 23:14

Gold IV

문제(출처: https://www.acmicpc.net/problem/3425)

< 고스택 >

 

문제 풀이 & 생각

 

stack을 사용해서 문제를 해결하며 예외 조건을 잘 구현해야 한다.

 

예외 조건

1) POP, INV, DUP 일 때 stack이 비어있으면 ERROR이다.

2) SWP 일 때 stack의 크기가 2보다 작으면 ERROR이다.

3) ADD, SUB, MUL, DIV, MOD 일 때 stack의 크기가 2보다 작으면 ERROR이다.

4) 각 연산이 1000000000보다 크면 ERROR이다.

5) DIV와 MOD 일 때 0으로 나누는 경우는 ERROR이다.

6) 최종 stack의 크기가 1이 아니면 ERROR이다.

 

 

 my solution (Java)

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.Stack;

public class _3425_ { // 고스택

	public static void main(String[] args) throws IOException {
		BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
		BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));

		Stack<Integer> stack = new Stack<>();
		ArrayList<String> arr = new ArrayList<>();

		String input = "";
		while (!(input = bf.readLine()).equals("QUIT")) {

			while (!input.equals("END")) {
				arr.add(input);
				input = bf.readLine();
			}
			int n = Integer.parseInt(bf.readLine());
			for (int i = 0; i < n; i++) {
				int num = Integer.parseInt(bf.readLine());
				stack.add(num);
				boolean flag = false;
				for (int j = 0; j < arr.size(); j++) {
					String str[] = arr.get(j).split(" ");
					if (str[0].equals("NUM"))
						stack.add(Integer.parseInt(str[1]));
					else if (str[0].equals("POP")) {
						if (stack.size() == 0) {
							flag = true;
							break;
						}
						stack.pop();
					} else if (str[0].equals("INV")) {
						if (stack.size() == 0) {
							flag = true;
							break;
						}
						stack.set(stack.size()-1, -stack.peek());
					} else if (str[0].equals("DUP")) {
						if (stack.size() == 0) {
							flag = true;
							break;
						}
						stack.add(stack.peek());
					} else if (str[0].equals("SWP")) {
						if (stack.size() < 2) {
							flag = true;
							break;
						}
						int a=stack.pop();
						int b=stack.pop();
						stack.add(a);
						stack.add(b);
					} else {
						if (stack.size() < 2) {
							flag = true;
							break;
						}
						int a = stack.pop();
						int b = stack.pop();
						if (str[0].equals("ADD")) {
							if(Math.abs((long)a + (long)b) > 1000000000) {
								flag=true;
								break;
							}
							stack.add(a + b);
						} else if (str[0].equals("SUB")) {
							if(Math.abs((long)b - (long)a) > 1000000000) {
								flag=true;
								break;
							}
							stack.add(b - a);
						} else if (str[0].equals("MUL")) {
							if(Math.abs((long)a * (long)b) > 1000000000) {
								flag=true;
								break;
							}
							stack.add(a * b);
						} else if (str[0].equals("DIV")) {
							if (a == 0 ) {
								flag = true;
								break;
							}
							if ((a < 0 && b < 0) || (a > 0 && b > 0)) {
								stack.add(Math.abs(b) / Math.abs(a));
							} else {
								stack.add(-(Math.abs(b) / Math.abs(a)));
							}
						} else if (str[0].equals("MOD")) {
							if (a == 0) {
								flag = true;
								break;
							}
							if (b < 0) {
								stack.add(-(Math.abs(b) % Math.abs(a)));
							} else {
								stack.add(Math.abs(b) % Math.abs(a));
							}
						}
					}
				}
				if (flag || stack.size() != 1) {
					bw.write("ERROR\n");
				} else {
					bw.write(stack.pop() + "\n");
				}
				stack.clear();
			}
			arr.clear();
			bw.write("\n");
			bf.readLine();
		}
		bw.flush();
	}
}

 

Main

- stack : 숫자 저장

  arr : 명령어 저장

- 입력어가 QUIT가 아닐 때 반복 -> 명령어가 END가 아닐 때까지 입력받아 arr에 저장 -> 프로그램 수행 횟수(N) 입력 -> 입력값(num) 입력받아 stack에 저장 -> 명령어만큼 반복하여 명령어 수행

- NUM일 때 stack에 값 저장

  POP일 때 stack이 비어있지 않으면 pop

  INV일 때 stack이 비어있지 않으면 첫 번째 수의 부호를 바꿈

  DUP일 때 stack이 비어있지 않으면 첫 번째 숫자를 stack에 저장

  SWP일 때 stack의 크기가 2보다 작지 않으면 숫자의 위치를 바꿈

  그 외에 명령어일 경우 먼저 stack의 크기를 확인하여 2보다 작으면 ERROR이므로 종료

   ADD일 때 두 숫자의 합이 1000000000보다 크지 않으면 합을 stack에 저장

   SUB일 때 두 숫자의 차가 1000000000보다 크지 않으면 차를 stack에 저장

   MUL일 때 두 숫자의 곱이 1000000000보다 크지 않으면 곱을 stack에 저장

   DIV일 때 0으로 나누는 것이 아니라면 절댓값을 씌운 뒤 몫을 구함 -> 피연산자 둘 다 음수이거나 양수인 경우 부호는 양수/ 그 외에는 부호는 음수로 저장

   MOD일 때 0으로 나누는 것이 아니라면 절댓값을 씌운 뒤 몫을 구함 -> 피제수의 부호와 같게 저장

- flag가 true이며 stack의 크기가 1이 아니라면 ERROR 출력

  그 외 stack의 값을 출력 후 다음 입력값을 위해 stack 비움

- 다음 기계를 위해  arr 비움

 



 

'🌞Algorithm > 🔥Baekjoon' 카테고리의 다른 글

[Baekjoon] 17299_오등큰수  (0) 2023.06.28
[Baekjoon] 17298_오큰수  (0) 2023.06.28
[Baekjoon] 14267_회사 문화 1  (0) 2023.06.27
[Baekjoon] 16562_친구비  (0) 2023.06.27
[Baekjoon] 1043_거짓말  (0) 2023.06.26