문제(출처: 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 |