[DFS완탐]백준_연산자끼워넣기
간단해 보이지만 나에게는 어려웠다... 일단 읽자마자 완탐을 해야겠다는 생각은 했다.
처음에는 for문으로 돌려야겠다는 생각을 했다. 연산자를 순열로 배열시킨다음 하나하나 for문으로 계산해주어야겠다고
생각했지만 순열로 나타내는게 쉽지 않았다.
완탐생각을 하면 제일 먼저 재귀함수를 생각해보는것이 좋은것 같다.
*재귀함수를 사용할때 보통 파라미터로 계산할 결과를 넣어주는데 흔히 내가 했던 착각은 이미 파라미터를 넣어줄 때 계산이 되서 다음 재귀로 들어가서 return과정을 만나는데 (한단계전에서 연산이 이루어짐) 이 부분을 착각해서
함수가 돌아가는 구조자체가 헷갈렸다.
그리고 재귀를 해줄때 완전탐색을 하기위해서는 ++ , -- 과정이 필요하다. 다른 재귀에서 원상태로 복구를 해줘야 하기때문!!.
문제
N개의 수로 이루어진 수열 A1, A2, ..., AN이 주어진다. 또, 수와 수 사이에 끼워넣을 수 있는 N-1개의 연산자가 주어진다. 연산자는 덧셈(+), 뺄셈(-), 곱셈(×), 나눗셈(÷)으로만 이루어져 있다.
우리는 수와 수 사이에 연산자를 하나씩 넣어서, 수식을 하나 만들 수 있다. 이때, 주어진 수의 순서를 바꾸면 안된다.
예를 들어, 6개의 수로 이루어진 수열이 1, 2, 3, 4, 5, 6이고, 주어진 연산자가 덧셈(+) 2개, 뺄셈(-) 1개, 곱셈(×) 1개, 나눗셈(÷) 1개인 경우에는 총 60가지의 식을 만들 수 있다. 예를 들어, 아래와 같은 식을 만들 수 있다.
- 1+2+3-4×5÷6
- 1÷2+3+4-5×6
- 1+2÷3×4-5+6
- 1÷2×3-4+5+6
식의 계산은 연산자 우선 순위를 무시하고 앞에서부터 진행해야 한다. 또, 나눗셈은 정수 나눗셈으로 몫만 취한다. 음수를 양수로 나눌 때는 C++14의 기준을 따른다. 즉, 양수로 바꾼 뒤 몫을 취하고, 그 몫을 음수로 바꾼 것과 같다. 이에 따라서, 위의 식 4개의 결과를 계산해보면 아래와 같다.
- 1+2+3-4×5÷6 = 1
- 1÷2+3+4-5×6 = 12
- 1+2÷3×4-5+6 = 5
- 1÷2×3-4+5+6 = 7
N개의 수와 N-1개의 연산자가 주어졌을 때, 만들 수 있는 식의 결과가 최대인 것과 최소인 것을 구하는 프로그램을 작성하시오.
입력
첫째 줄에 수의 개수 N(2 ≤ N ≤ 11)가 주어진다. 둘째 줄에는 A1, A2, ..., AN이 주어진다. (1 ≤ Ai ≤ 100) 셋째 줄에는 합이 N-1인 4개의 정수가 주어지는데, 차례대로 덧셈(+)의 개수, 뺄셈(-)의 개수, 곱셈(×)의 개수, 나눗셈(÷)의 개수이다.
출력
첫째 줄에 만들 수 있는 식의 결과의 최댓값을, 둘째 줄에는 최솟값을 출력한다. 최댓값과 최솟값이 항상 -10억보다 크거나 같고, 10억보다 작거나 같은 결과가 나오는 입력만 주어진다. 또한, 앞에서부터 계산했을 때, 중간에 계산되는 식의 결과도 항상 -10억보다 크거나 같고, 10억보다 작거나 같다.
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 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | import java.awt.Point; import java.util.Arrays; import java.util.LinkedList; import java.util.Queue; import java.util.Scanner; public class Main { static int N ; static int[] M; static int[] Q; static int max = Integer.MIN_VALUE; static int min = Integer.MAX_VALUE; public static void dfs(int num,int len) { if(len==N-1) { //len을 return의 조건으로 쓰기 위해 도입. max = num >= max ? num : max; min = num <= min ? num : min; return; } if(Q[0]>0) { Q[0]--; dfs(num+M[len+1],len+1); Q[0]++; } if(Q[1]>0) { Q[1]--; dfs(num-M[len+1],len+1); Q[1]++; } if(Q[2]>0) { Q[2]--; dfs(num*M[len+1],len+1); Q[2]++; } if(Q[3]>0) { Q[3]--; dfs(num/M[len+1],len+1); Q[3]++; } } public static void main(String args[]){ Scanner sc = new Scanner(System.in); N = sc.nextInt(); M = new int[N]; for(int i=0;i<N;i++) M[i]=sc.nextInt(); Q = new int[4]; for(int i=0;i<4;i++) Q[i]=sc.nextInt(); dfs(M[0],0); System.out.println(max+"\n"+min); } } | cs |