요즘 코딩테스트 속성 준비 강의를 듣고 있다.
(https://skillflo.io/course/10459?productId=18173&tab=info
이 강의 part5를 수강중이다.)
강의를 듣기전 일단 먼저 문제를 풀었다.
내가 처음 제출한 코드는 이렇다. 다행히(?) 한번에 통과했다.
#include <iostream>
#include <vector>
#include <limits>
using namespace std;
int N;
vector<int> numV;
vector<int> oper(4, 0);
int minAns = numeric_limits<int>::max();
int maxAns = numeric_limits<int>::min();
// 입력
void input() {
// 숫자 갯수 받기
cin >> N;
int temp;
// 숫자 벡터 채우기
for (int i = 0; i < N; i++) {
cin >> temp;
numV.push_back(temp);
}
// 연산자 벡터 채우기
for (int i = 0; i < 4; i++) {
cin >> oper[i];
}
}
int sum(int a, int b) {
return a + numV[b];
}
int sub(int a, int b) {
return a - numV[b];
}
int mul(int a, int b) {
return a * numV[b];
}
int di(int a, int b) {
if (a < 0) {
return (-1) * ((-1 * a) / numV[b]);
}
return a / numV[b];
}
void rec_func(int k, int ans) {
// 연산완료
if (k == N) {
if (minAns > ans) {
minAns = ans;
}
if (maxAns < ans) {
maxAns = ans;
}
return;
}
// 연산
for (int i = 0; i < 4; i++) {
if (oper[i] == 0) {
continue;
}
// 연산 후 다음단계 이동
oper[i]--;
switch(i) {
case 0:
rec_func(k + 1, sum(ans, k));
break;
case 1:
rec_func(k + 1, sub(ans, k));
break;
case 2:
rec_func(k + 1, mul(ans, k));
break;
case 3:
rec_func(k + 1, di(ans, k));
break;
}
// 연산자 변경
oper[i]++;
continue;
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
input();
rec_func(1, numV[0]);
// 결과 출력
cout << maxAns << "\n" << minAns;
return 0;
}
현재 수강중인 내용은 완전탐색. 완전탐색이라서기보다는 언제읽어도 무슨 코드인지 알 수 있게 지금은 가독성 중시 및 모듈화하는 연습을 하고 있다.
사실 처음에는 이게 모듈화 최선인줄 알았다.
수강 후 수정한 코드는 이렇다.
#include <iostream>
#include <vector>
#include <limits>
using namespace std;
int N;
vector<int> numV;
vector<int> operators(4, 0);
int minAns = numeric_limits<int>::max();
int maxAns = numeric_limits<int>::min();
// 입력
void input() {
// 숫자 갯수 받기
cin >> N;
int temp;
// 숫자 벡터 채우기
for (int i = 0; i < N; i++) {
cin >> temp;
numV.push_back(temp);
}
// 연산자 벡터 채우기
for (int i = 0; i < 4; i++) {
cin >> operators[i];
}
}
// 계산 함수
int calc(int operand1, int oper, int operand2) {
switch(oper) {
case 0:
return operand1 + operand2;
case 1:
return operand1 - operand2;
case 2:
return operand1 * operand2;
case 3:
if (operand1 < 0) {
return -1 * ((-1 * operand1) / operand2);
}
return operand1 / operand2;
}
}
void rec_func(int k, int ans) {
// 연산완료
if (k == N) {
if (minAns > ans) {
minAns = ans;
}
if (maxAns < ans) {
maxAns = ans;
}
return;
}
// 연산
for (int i = 0; i < 4; i++) {
if (operators[i] == 0) {
continue;
}
// 연산 후 다음단계 이동
operators[i]--;
rec_func(k + 1, calc(ans, i, numV[k]));
// 연산자 변경
operators[i]++;
continue;
}
}
int main() {
// 최적화
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
// 입력 + 연산 + 출력
input();
rec_func(1, numV[0]);
cout << maxAns << "\n" << minAns;
return 0;
}
계산을 여기저기서 할게 아니라 '계산'이라는 함수를 따로 만드는게 더 깔끔하다는 걸 알았다.
아무래도 계속 연습하는 것만이 답인 것 같다. 이 함수가 어디까지를 책임질지를 잘 고민해봐야겠다.
어찌보면 이 또한도 객체지향적인 코드를 짜는 연습이 되지 않을까 싶다. (요즘 많이 고민하는 부분 ㅎㅎ)