PS

백준 16638번 괄호 추가하기2

남마허 2020. 3. 15. 23:37

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

 

16638번: 괄호 추가하기 2

첫째 줄에 수식의 길이 N(1 ≤ N ≤ 19)가 주어진다. 둘째 줄에는 수식이 주어진다. 수식에 포함된 정수는 모두 0보다 크거나 같고, 9보다 작거나 같다. 문자열은 정수로 시작하고, 연산자와 정수가 번갈아가면서 나온다. 연산자는 +, -, * 중 하나이다. 여기서 *는 곱하기 연산을 나타내는 × 연산이다. 항상 올바른 수식만 주어지기 때문에, N은 홀수이다.

www.acmicpc.net

 

 

 

 

 

<접근방법>

괄호가 가장 우선순위입니다. 그 다음으로 곱셈이 나머지 연산보다 우선순위입니다.

단순히 생각한대로 구현하기만 하면 되는 문제이지만 구현 디테일이 조금 까다로웠던 문제입니다.

 

저는 괄호만 일괄적으로 계산, 곱셈만 일괄적으로 계산, 나머지 계산하는 순서로 풀었습니다.

 

<느낀 점>

 

 


 

 

 

<코드>

#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
#include <limits.h>
#include <memory.h>
using namespace std;

int n, lim, res = INT_MIN;
bool visit[20];
string str;

int cal(int a, int b, char c) {
	int x = 0;
	switch (c) {
	case '*': x = a * b; break;
	case '+': x = a + b; break;
	case '-': x = a - b; break;
	}
	return x;
}

void simul3(vector<string> v) {
	int sum;
	string a;

	a = v[0];
	sum = stoi(a);
	for (int i = 1; i < (int)v.size(); i += 2) {
		sum = cal(stoi(a), stoi(v[i+1]), v[i][0]);
		a = to_string(sum);
	}
	res = max(res, sum);
}

void simul2(vector<string> v) {
	vector<string> s;
	string a;
	a = v[0];
	s.push_back(a);
	for (int i = 1; i < (int)v.size(); i += 2) {
		if (v[i][0] == '*') {
			string a = s.back();
			s.pop_back();
			s.push_back(to_string(cal(stoi(a), stoi(v[i+1]), '*')));
		}
		else {
			string a, b;
			a = v[i];
			s.push_back(a);

			b = v[i + 1];
			s.push_back(b);
		}
	}

	simul3(s);
}

 void simul1() {
	 vector<string> s;
	 string a;
	 a.push_back(str[0]);
	 s.push_back(a);
	for (int i = 1; i < n; i += 2) {
		if (visit[i]) {
			s.pop_back();
			s.push_back(to_string(cal(str[i-1] - '0', str[i+1] - '0', str[i])));
		}
		else {
			string a, b;
			a.push_back(str[i]);
			s.push_back(a);

			b.push_back(str[i + 1]);
			s.push_back(b);
		}
	}

	simul2(s);

}

void dfs(int dep, int start) {
	if (dep == lim) {
		simul1();
		return;
	}

	for (int i = start; i < n; i ++) {
		if (i % 2 == 0) continue;
		if (visit[i]) continue;
		if (i-2 >= 0 && visit[i-2]) continue;
		
		visit[i] = true;
		dfs(dep + 1, i + 1);
		visit[i] = false;
	}
}

int main() {
	cin >> n >> str;

	int sz = n / 2;
	for (int i = 0; i <= sz; i++) {
		memset(visit, false, sizeof(visit));
		lim = i;

		dfs(0, 0);
	}
	cout << res << '\n';
	return 0;
}

 

 

반응형