[Silver II] 도영이가 만든 맛있는 음식 - 2961

JYC·2024년 8월 7일

[BAEKJOON]

목록 보기
87/102

문제 링크

성능 요약

메모리: 14184 KB, 시간: 100 ms

분류

백트래킹, 비트마스킹, 브루트포스 알고리즘

제출 일자

2024년 8월 7일 23:45:10

문제 설명

도영이는 짜파구리 요리사로 명성을 날렸었다. 이번에는 이전에 없었던 새로운 요리에 도전을 해보려고 한다.

지금 도영이의 앞에는 재료가 N개 있다. 도영이는 각 재료의 신맛 S와 쓴맛 B를 알고 있다. 여러 재료를 이용해서 요리할 때, 그 음식의 신맛은 사용한 재료의 신맛의 곱이고, 쓴맛은 합이다.

시거나 쓴 음식을 좋아하는 사람은 많지 않다. 도영이는 재료를 적절히 섞어서 요리의 신맛과 쓴맛의 차이를 작게 만들려고 한다. 또, 물을 요리라고 할 수는 없기 때문에, 재료는 적어도 하나 사용해야 한다.

재료의 신맛과 쓴맛이 주어졌을 때, 신맛과 쓴맛의 차이가 가장 작은 요리를 만드는 프로그램을 작성하시오.

입력

첫째 줄에 재료의 개수 N(1 ≤ N ≤ 10)이 주어진다. 다음 N개 줄에는 그 재료의 신맛과 쓴맛이 공백으로 구분되어 주어진다. 모든 재료를 사용해서 요리를 만들었을 때, 그 요리의 신맛과 쓴맛은 모두 1,000,000,000보다 작은 양의 정수이다.

출력

첫째 줄에 신맛과 쓴맛의 차이가 가장 작은 요리의 차이를 출력한다.

풀이 (백트래킹)

이 문제에서 생각해야 할 가장 중요한 건 경우의 수라고 생각한다.

이 문제는 신맛과 쓴맛의 차이가 가장 작은 요리의 차이를 구해야 하는 문제이다.
이는 두가지 경우를 통해 값을 찾아나갈 수 있다.

  • i번 재료를 넣는다.
  • i번 재료를 넣지 않는다.

재료의 개수 N(1 ≤ N ≤ 10)는 최대 10개라고 나와있다.
즉 각 재료를 넣을지 말지를 모두 검사해주면서 모든 경우의 수를 따져가며 값을 찾으면 된다!

필자는 "모든 재료를 사용해서 요리를 만들었을 때, 그 요리의 신맛과 쓴맛은 모두 1,000,000,000보다 작은 양의 정수이다." 라는 설명에서 혹여나 int 범위를 넘길까 long으로 각각의 변수를 설정했다.
하지만 다른 여러 풀이를 보니 굳이 long으로 바꿀 필요는 없어보인다.

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class baekjoon_2961 {
	static long[][] taste;
	static long ans=Long.MAX_VALUE;
	static int n;
	public static void main(String[] args) throws IOException{
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st;
		n = Integer.parseInt(br.readLine());
		taste = new long[n][2];
		
		for(int i=0; i<n; i++) {
			st = new StringTokenizer(br.readLine());
			taste[i][0]=Integer.parseInt(st.nextToken());
			taste[i][1]=Integer.parseInt(st.nextToken());
		}
		
		backtracking(0,1,0,0);
		System.out.println(ans);
	}
	public static void backtracking(int cnt,long sour, long bitter,int select) {
		if(cnt==n) {
			if(select!=0 && Math.abs(sour - bitter)<ans) {
				ans = Math.abs(sour - bitter);
			}
			return;
		}
		
		//두가지 경우 - cnt번 재료를 사용할 것인지 아닌지
		backtracking(cnt+1,sour*taste[cnt][0],bitter+taste[cnt][1],select+1);
		backtracking(cnt+1,sour,bitter,select);
	}
}
profile
열심히 하기 1일차

0개의 댓글