티스토리 뷰
문제
programmers.co.kr/learn/courses/30/lessons/67257
코딩테스트 연습 - 수식 최대화
IT 벤처 회사를 운영하고 있는 라이언은 매년 사내 해커톤 대회를 개최하여 우승자에게 상금을 지급하고 있습니다. 이번 대회에서는 우승자에게 지급되는 상금을 이전 대회와는 다르게 다음과
programmers.co.kr
풀이
1. 우선 구해야하는건 + , - , * 의 서로 다른 연산자 우선순위 3!가지 순열을 구성해보고 모든 연산결과의 최소를 구하는 것입니다.
2. 입력으로 받은 문자열에 숫자와 연산자가 섞여있으므로 주어진 식을 파싱해가며 우선순위가 서로 다른 연산자 식을 계산하기 간편하게 중위표기식에서 후위표기식으로 변환해줍니다.
3. 중위표기식에서 후위표기식(post)으로 바꾸는건 연산자를 넣어두는 벡터(op)를 사용하며 op는 항상 위쪽의 연산자가 우선순위가 높도록 유지합니다. post로 바꾸는 방법은 아래와 같습니다.
-
현재 보고있는 문자가 연산자일 때, 현재까지 모아놓은 숫자는 그냥 post에 넣어줍니다.
-
현재 보고있는 연산자가 op에 들어있는 연산자보다 우선순위가 작다면 op에 들어있는 연산자를 post에 넣어주고, 현재 보고있는 연산자를 op에 넣어줍니다.
-
입력받은 문자열을 전부 순회한 후, op에 남아있는 연산자는 위쪽부터 post에 담아줍니다.
4. 마지막으로 계산을 할 때, post에 담긴 숫자들은 따로 숫자들을 담는 벡터(num)에 관리해주며 post를 순회하며 연산자를 만났을 때 num에서 숫자를 두 개 팝하는데 이때 팝해서 나온 숫자는 먼저 나오는 숫자가 연산자 뒤에 나오는 숫자인걸 조심하면 됩니다.
-
(ex) 12- 의 경우 1 - 2가 맞는식이지만 num에서 나오는 숫자를 차례대로 계산하면 2 - 1이 됨. 따라서 먼저 나오는 숫자가 연산자 뒤 숫자
풀이
#include <bits/stdc++.h>
using namespace std;
#define pb push_back
#define all(x) (x).begin(), (x).end()
#define sz(v) ((int)(v).size())
typedef long long ll;
vector<int> v;
// 연산자를 인덱스로 변환
int conv(string x) {
if (x == "+") return 0;
else if (x == "-") return 1;
return 2;
}
// 앞쪽 연산자의 우선순위가 앞선다면 양수를, 아니면 음수를 반환하는 비교함수
int calop(string a, string b) {
if (v[conv(a)] > v[conv(b)]) return 1;
else if (v[conv(a)] < v[conv(b)]) return -1;
return 0;
}
ll solution(string e) {
ll ans = 0;
for (int i = 0; i < 3; i++) v.pb(i);
do {
string tmp = "";
vector<string> post, op; // 연산자우선순위가 op.back()으로 갈수록 커지도록 유지한다.
vector<ll> num;
// parsing & convert to postfix
for (int i = 0; i < sz(e); i++) {
if (e[i] == '+' || e[i] == '-' || e[i] == '*') {
string curop = ""; curop += e[i];
if (!tmp.empty()) post.pb(tmp), tmp = "";
while (!op.empty() && calop(op.back(), curop) >= 0) {
post.pb(op.back());
op.pop_back();
}
op.pb(curop);
}
else tmp += e[i];
}
if (!tmp.empty()) post.pb(tmp);
while (!op.empty()) post.pb(op.back()), op.pop_back();
// calculate
for (int i = 0; i < sz(post); i++) {
string c = post[i];
if (c == "+" || c == "-" || c == "*") {
ll b = num.back(); num.pop_back();
ll a = num.back(); num.pop_back();
if (c == "+") num.pb(a + b);
else if (c == "-") num.pb(a - b);
else num.pb(a * b);
}
else num.pb(stoll(c));
}
ans = max(ans, abs(num[0]));
} while (next_permutation(all(v)));
return ans;
}
'Algorithm > Programmers' 카테고리의 다른 글
[프로그래머스 2020 카카오 인턴십] 경주로 건설 (0) | 2020.10.31 |
---|---|
[프로그래머스 2020 카카오 인턴십] 보석 쇼핑 (0) | 2020.10.31 |
[프로그래머스 2020 카카오 인턴십] 키패드 누르기 (0) | 2020.10.31 |
[프로그래머스 2020 KAKAO BLIND RECRUITMENT] 자물쇠와 열쇠 (0) | 2020.09.04 |
[프로그래머스 2020 KAKAO BLIND RECRUITMENT] 괄호 변환 (0) | 2020.09.04 |
- Total
- Today
- Yesterday
- 이분탐색
- 누적합
- 2022 카카오 블라인드 코딩테스트
- 프로그래머스 월간코드챌린지
- 트리
- 구현
- 표 편집
- 동적계획법
- Kakaoblind
- 2021 KAKAO BLIND
- 2020 KAKAO BLIND RECRUITMENT
- 유니온파인드
- 프로그래머스 위클리 9주차
- 카카오 인턴십
- BFS
- DP
- 2022 KAKAO BLIND RECRUITMENT
- 백준
- 카카오 2020 인턴십
- 2022 카카오블라인드
- 게임이론
- 프로그래머스
- 파싱
- 카카오 표 편집
- 2021 카카오 블라인드
- 위클리 챌린지
- 투포인터
- 시뮬레이션
- 카카오 2021
- 카카오 2차코딩테스트
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |