Problem Solving/Baekjoon Online Judge
BOJ/백준 19591 독특한 계산기
khj1999
2024. 9. 19. 18:17
https://www.acmicpc.net/problem/19591
해결 아이디어
문자열 처리 부분만 잘 해주고 조건에 맞게 잘 비교하면 되는 문제였다
#include <iostream>
#include <deque>
#include <string>
#include <cstdlib>
using namespace std;
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
string str;
cin >> str;
deque<long long> num;
deque<char> op;
string number = "";
bool sign = false; // 부호 판별 변수 시작할때 음수 판별
int len = str.length();
for(int i = 0; i < len; i++){
if(i == 0 && str[i] == '-') sign = true;
else if(!isdigit(str[i])){ // 숫자가 아니면
op.push_back(str[i]); // 연산자를 디큐에 넣고
long long tmp = stoll(number); // 임시 숫자 변수를 long long 타입으로 변환
if(sign){ // 음수 일때
tmp *= -1;
sign = false;
}
num.push_back(tmp); // 숫자 deque에 push
number = ""; // 초기화
}
else{
number += str[i]; // 숫자 이면 계속 문자열에 이어 붙여 줌
// 1+2*90 이럴 경우 1, 2, 90 으로 넣어야 하기 때문
}
// 만약 모든 요소에 대한 검사가 끝나면 마지막 요소를 추가
if(i == len - 1){
long long tmp = stoll(number);
if(sign){
tmp *= -1;
sign = false;
}
num.push_back(tmp);
number = "";
}
}
// 계산하는 함수 현재 인덱스와 + 1 인덱스를 계산
auto calc = [](deque<long long>& num, int idx, char op) -> long long {
if(op == '*') return num[idx] * num[idx + 1];
else if(op == '/') return num[idx] / num[idx + 1];
else if(op == '+') return num[idx] + num[idx + 1];
else return num[idx] - num[idx + 1];
};
// 비교 함수
auto cmp = [](char op) -> int {
if(op == '*' || op == '/') return 2;
else return 1;
};
// 숫자가 1개가 남을 때 까지
while(num.size() > 1 && !op.empty()){
char op_front = op.front(), op_rear = op.back();
long long cur_front = 0, cur_rear = num.size() - 2;
long long calc_front = calc(num, cur_front, op_front), calc_rear = calc(num, cur_rear, op_rear);
bool front = false, rear = false;
// 우선순위 비교 곱셈, 나눗셈인지 앞 계산 결과가 큰지 뒤가 큰지
if(cmp(op_front) > cmp(op_rear)) front = true;
else if(cmp(op_front) < cmp(op_rear)) rear = true;
else if(calc_front >= calc_rear) front = true;
else rear = true;
// 앞의 계산부터 진행할 경우
if(front){
num.pop_front();
num.pop_front();
num.push_front(calc_front);
op.pop_front();
}
// 뒤의 계산부터 진행 할 경우
else{
num.pop_back();
num.pop_back();
num.push_back(calc_rear);
op.pop_back();
}
}
// 정답 출력
cout << num.front();
return 0;
}
문제는 풀면서 어처구니 없는 실수를 너무 많이 했다.
long long을 써야하는데 int를 사용해서 틀리거나,
// 계산하는 함수 현재 인덱스와 + 1 인덱스를 계산
auto calc = [](deque<long long>& num, int idx, char op) -> long long {
if(op == '*') return num[idx] * num[idx + 1];
else if(op == '/') return num[idx] / num[idx + 1];
else if(op == '+') return num[idx] + num[idx + 1];
else return num[idx] - num[idx + 1];
};
여기서 &을 사용하지 않고 참조가 아닌 복사로 보내주면 시간초과가 발생한다 숫자의 범위가 커서 매우 많은 데이터를 복사한다고
그런 일이 발생 한 것 같았다.