반응형
리뷰
처음엔 최악의 케이스만 생각하여 시간내에 가능 할까? 라는 생각이 들었는데 생각보다 여유롭게 풀렸다.
백트래킹이나 DFS는 생각이 너무 많아지면 더 어려운 문제인 것 같다.
문제 풀이
- 각 테스크 케이스 마다 min_val은 아주 큰 값으로, max_val은 아주 작은 값으로 초기화를 해준다.
- 숫자의 개수와 부호의 개수를 각각 받아와 주고 각 숫자를 배열에 입력 받아준다.
- 재귀의 깊이를 나타낼 level과 연산에 사용할 숫자를 매개변수로 백트래킹을 통해 완전 탐색을 실행해준다.
- 모든 완전 탐색을 마친 뒤 각 테스트 케이스마다 max_val - min_val 값을 출력해 주면 된다.
참고 사항
dfs 함수 정보
- 기저 조건 : level이 n - 1에 도달했을 경우 max_val과 min_val을 최신화
- 반복문 : 연산자의 개수는 총 4개이므로 4번의 반복문을 실행
- 판별식 : if (op[i]) 만약 현재 연산자가 사용 가능한지를 판별
- 재귀 이전 : 판별식이 참인 경우이므로 op[i]의 개수를 1개 빼준다.
- 재귀 : level + 1, 각 연산자에 맞는 연산을 val과 다음 숫자를 통해 연산해 준 값을 재귀 처리 해준다.
- 재귀 후 : 재귀 이전 빼주었던 op[i]의 개수를 1개 더해주어 원상 복구 해준다.
정답 코드
#include<iostream>
using namespace std;
int tc, n, min_val, max_val;
int op[4];
int nums[13];
void dfs(int level, int val) {
if (level == n - 1) {
max_val = max(max_val, val);
min_val = min(min_val, val);
return;
}
for (int i = 0; i < 4; i++) {
if (op[i]) {
op[i]--;
if (i == 0) dfs(level + 1, val + nums[level + 1]);
if (i == 1) dfs(level + 1, val - nums[level + 1]);
if (i == 2) dfs(level + 1, val * nums[level + 1]);
if (i == 3) dfs(level + 1, val / nums[level + 1]);
op[i]++;
}
}
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
cin >> tc;
for (int c = 1; c <= tc; c++) {
min_val = 999999999, max_val = -999999999;
cin >> n >> op[0] >> op[1] >> op[2] >> op[3];
for (int i = 0; i < n; i++) cin >> nums[i];
dfs(0, nums[0]);
cout << "#" << c << " " << max_val - min_val << "\n";
}
}
728x90
반응형
'알고리즘 공부 > C++' 카테고리의 다른 글
SWEA 1952번 [모의 SW 역량테스트] 수영장 C++ 백트래킹 (0) | 2024.08.18 |
---|---|
SWEA 2115번 [모의 SW 역량테스트] 벌꿀채취 C++ 백트래킹, 완전 탐색 (0) | 2024.08.18 |
백준 20040번 사이클 게임 C++ 유니온 파인드, 분리 집합 (0) | 2024.08.18 |
백준 1504번 특정한 최단 경로 C++ 다익스트라, 최단 경로 (0) | 2024.08.18 |
백준 13537번 수열과 쿼리 1 C++ 세그먼트 트리, 머지 소트 트리 (0) | 2024.08.17 |