14888번: 연산자 끼워넣기 (acmicpc.net)
문제분석
N개의 수로 이루어진 수열 A1, A2, ..., AN과 수와 수 사이에 끼워넣을 수 있는 N-1개의 연산자(+, -, *, /)가 주어졌을 때, 최대값과 최소값을 구하는 문제다.
이 때, 주어진 수의 순서는 바꿀 수 없고, 식의 계산은 연산자 우선 순위를 무시하고 앞에서부터 차례대로 진행해야 한다.
- 입력: 첫째 줄에 수의 개수 N(2 ≤ N ≤ 11)가 주어진다. 둘째 줄에는 A1, A2, ..., AN이 주어진다. (1 ≤ Ai ≤ 100) 셋째 줄에는 합이 N-1인 4개의 정수가 주어지는데, 차례대로 덧셈(+)의 개수, 뺄셈(-)의 개수, 곱셈(×)의 개수, 나눗셈(÷)의 개수이다.
- 출력: 첫째 줄에 만들 수 있는 식의 결과의 최댓값을, 둘째 줄에는 최솟값을 출력한다.
코드
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int N;
int A[11];
int op[4];
ll maxResult = -10e10;
ll minResult = 10e10;
void dfs(int opNum, int res) {
if (opNum == N - 1) { //기저사례 (N-1개의 연산자를 사용했으면 종료)
if (res > maxResult) maxResult = res;
if (res < minResult) minResult = res;
return;
}
for (int i = 0; i < 4; i++) {
if (op[i] > 0) { //해당 연산자 개수가 남아있으면 사용
op[i]--; //해당 연산자 개수 줄이고
opNum++; //사용한 총 연산자 개수 늘리고
if (i == 0) dfs(opNum, res + A[opNum]); //사용한 총 연산자 개수를 늘리고 결과값과 함께 다음으로
else if (i == 1) dfs(opNum, res - A[opNum]);
else if (i == 2) dfs(opNum, res * A[opNum]);
else if (i == 3) dfs(opNum, res / A[opNum]);
op[i]++; //다른 연산자도 써보기 위해 초기화
opNum--;
}
}
return;
}
void solveProblem() {
dfs(0, A[0]);
cout << maxResult << "\n" << minResult;
}
void getInput() {
cin >> N;
for (int i = 0; i < N; i++) cin >> A[i];
for (int i = 0; i < 4; i++) cin >> op[i];
}
int main() {
ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
getInput();
solveProblem();
return 0;
}
문제풀이
재귀를 통한 Bruteforce 방식으로 문제를 해결했다.
1. 연산자의 개수는 op[] 배열에, 수열은 A[] 배열에 입력받는다.
2. dfs 함수를 실행하는데, 아직 연산자를 하나도 사용하지 않았으므로 opNum=0, 결과값(res)은 수열의 첫 번째 값을 넘긴다.
3. 4개의 연산자에 대해서 for loop을 돌리면서, +, -, *, /를 순차적으로 모두 사용해본다.
4. 3번의 for loop을 수행하면서, 지금까지 사용한 연산자의 총 개수(opNum)와 연산의 결과값(res ? A[opNum])을 다음 재귀함수로 넘겨주다가, 사용한 연산자의 총 개수가 N-1개가 된다면(모두 사용했다면) 재귀를 마치고, 이 때의 결과값이 최대값보다 크다면 maxResult에, 최소값보다 작다면 minResult에 기록한다. (이 때, ?는 +, -, *, / 중 하나)
4. 모든 경우의 수를 따져보기 위해 for loop을 1회 수행할 때마다 op[i]와 opNum을 다시 되돌리면서 N-1개의 연산자에 대해서 모두 for loop을 돌릴 수 있도록 한다.
5. 모든 재귀를 마치면 maxResult와 minResult를 출력하고 끝낸다.
'Koala - 9기 > 코딩테스트 준비 스터디' 카테고리의 다른 글
[백준/15654] N과 M (5) (0) | 2023.01.08 |
---|---|
[백준/Python] 20410번 추첨상 사수 대작전! (Easy) (0) | 2023.01.08 |
[백준/python] 6603번 로또 (0) | 2023.01.07 |
[백준/JAVA]14501번 퇴사 (0) | 2023.01.06 |
[백준/Python] 6443번 애너그램 (0) | 2023.01.06 |