-
4012.요리사알고리즘/SW Expert Academy 2020. 8. 6. 22:41
이번에 풀어볼 문제는 SW Expert의 4012번 요리사이다.
지금까지 풀었던 SW Expert 문제 중에 문제가 가장 애매하게 출제된 거 같다.
그 이유는 식재료에 대한 중복내용이 없기 때문에 어떻게 풀어아햐는건지 확실하지 않다고 느꼈기 때문이다.
하여튼 간에 문제를 처음 읽어보면 어떤 부분이 애매한지 느낄 수 있을 것이다.
애매한 부분만 빼면 재귀함수를 연습하기에는 괜찮은 문제인 거 같다 => 나는 재귀를 잘못해서 조금 골치아팠다..
이 문제는 결론적으로 조합 문제이다. 결국 시너지를 만들어 내기 위함인데 두 가지의 조합이 들어가있다.
1. 음식A와 B에 대한 조합
=> 식재료의 갯수의 / 2를 선택하는 조합을 우선 구현해야한다.
=> 예를 들어 6가지의 식재료가 있다고하면 6개중 6/2 => 3개 즉 6개중 3개를 고르는 조합을 구현해야한다.
2. 그렇게 고른 3개의 식재료중 2개를 선택하는 조합
=> 3개중에 2개를 이용한 조합을 통해서 시너지의 크기를 구해야한다.
나는 재귀함수를 이용해서 조합을 만들었다.
개인적으로 식재료를 나눈거까지는 금방했는데 2번을 구현하는게 머리에 안떠올랐다..
이런 부분이 부족한 거 같다.. 부족한 부분을 찾아서 다행이다.
=> 정답을 보면 이걸 왜 못떠올렸나 싶다..( 21 ~ 27번 라인 )
< Code 설명 >
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
#pragma warning(disable:4996)#include <iostream>#include <deque>#include <algorithm>#define MAX 17using namespace std;int T, N;int map[MAX][MAX]; // 식재료 mapbool check[MAX]; // 식재료 사용여부int ans, syn;int sum1, sum2; // 음식A, 음식B의 시너지 변수deque<int>d1; // 음식 A의 식재료 그릇deque<int>d2; // 음식 B의 식재료 그릇void cook(){sum1 = sum2 = 0; // 0으로 초기화for (int i = 0; i < syn; i++){for (int j = 0; j < syn; j++){if (i != j ){sum1+=map[d1[i]][d1[j]]; // 음식 A의 시너지 구하기}}}for (int i = 0; i < syn; i++){for (int j = 0; j < syn; j++){if (i != j){sum2 += map[d2[i]][d2[j]]; // 음식 B의 시너지 구하기}}}d1.clear(); // 음식A의 식재료 그릇 비우기d2.clear(); // 음식B의 식재료 그릇 비우기ans = min(ans, abs(sum1 - sum2)); // 시너지의 차이 중 최소 값을 저장}void search(int start, int cnt){ // 시작 index와 고른 식재료의 개수를 인자로 조합 진행if (cnt == syn){ // 총 식재료중 절반을 골랐다면for (int i = 0; i < N; i++){if (check[i])d1.push_back(i); // 음식A에 선택한 식재료 저장elsed2.push_back(i); // 남은 식재료는 음식B에 사용되므로 따로 저장}cook(); // 음식만들기 시작! ( 고른 식재료들로 최대 시너지를 찾는 함수 )return;}for (int i = start; i < N; i++){ // 인자로 넘겨준 시작 idx를 사용하는것이 Point !!// 식재료 조합 재귀함수if (!check[i]){ // 고른적이 없다면check[i] = true; // 고른다search(i, cnt + 1); // 고른 갯수 +1check[i] = false; // 다음 탐색을 위해 고른것 취소}}}int main() {freopen("4012.txt", "r", stdin);cin >> T;for (int z = 1; z <= T; z++){cin >> N;for (int i = 0; i < N; i++){for (int j = 0; j < N; j++){cin >> map[i][j];}}ans = 987654321; // 정답변수syn = N / 2; // 식재료의 절반만 이용하여 시너지를 내야함search(0,0); // 조합시작cout << "#" << z << " " << ans << endl;}return 0;}cs 반응형'알고리즘 > SW Expert Academy' 카테고리의 다른 글
2112.보호필름 (0) 2020.07.30 1953.탈주범 검거 (1) 2020.07.28 1952.수영장 (0) 2020.07.23 2382.미생물격리 (0) 2020.07.21 2383.점심 식사시간 (0) 2020.07.10 댓글