/* 13:30 1907 탄소화합물 세 가지 종류의 원자 CHO 화합물을 탄소 화합물. 분자플분자는 분자 원자숫자워자숫자 분자는 하나이상의 원자로 구성 숫자는 2이상 9이하, 숫자엑스는 그 원자가 한 번만 나타났다. 우리가 관심이 있는 화학식이 딥니다. 균형이 있지 않다면 적절한 계수를 주어 화학식의 균형을 맞출 수 있습니다. 분자가 여러 개 있다는 것으로 생각합니다. 씨플 1,2,1의 계수를 주어 균형을 맞출 수 있다는 것 분자 플 분자는 분자 형태의 화학실 적절한 계수를 맞추어 균형있는 화학식으로 만드는 프로그램 H3 O3 *2 H6 O 12 O 6 H2 O4 * 3 H6 O 12 최소공배수 이런것들을 파악해야겠습니다. 빼는 개념으로 생각을 해야 하나요? C 의 갯수 H 의 갯수 O 의 갯수를 담는 배열을 만들고 빼면서 계산을 하도록 하겠습니다. 3번째것에서 1번째것을 뺴고, -1 이상이면 3번째 것을 곱하기 2한다음에, -1 값이 나오면 곱하기를 해주고 다시 빼도록 합니다. 아, 3개의 순열을 만들어서 1 1 1 1 1 2 1 1 3 이런식으로 각각 1~10 을 넣을 수 있습니다. 그리고 계산한 결과가 0이 되면 리턴하도록 합니다. 중복 가능 순열입니다. C H O 3 3 1 2 4 1 4 중복 가능한 순열 문제입니다. 1. 입력을 받고 계산하기 2. 중복 가능 순열 만들기 원하는 결과가 만들어지면 그곳에서 계산하기. 계산 결과가 0 이면 출력하고 끝내기 입력받는 것을 어떻게 구분하지. 일단 3개의 스트링으로 나누어야 하나? 스트링으로 나누고 뒤에서 부터 일단 언어가 나오면 1++ 하면 되고 숫자가 나오면 저장해두었다가 언어나오는 곳 ++ 하면 되겠습니다. */ #include <iostream> #include <string> #include <queue> using namespace std; int inputArr[51]; int CHO1[3], CHO2[3], CHO3[3]; int visit[10]; int store[3]; int num; string str; int a = 0, b = 0; int flag; /* C + CC = CCCCC HO3H2 + O = H2O2O2 CHO1[] H 그럼 다음 문자이면 H++ 로 끝내고 그 문자에 대해서 집중함. O 숫자이면 +=3 을 합니다. H1O3H2 이렇게 만들어야 할 것 같습니다. */ void problemIn() { cin >> str; for (int i = 0; b == 0; i++) { if (str[i] == '+') a = i; if (str[i] == '=') b = i; } for (int i = a-1; i >=0; i--) { if (str[i] == 'C') { if (num > 0) { CHO1[0] += num; num = 0; } else { CHO1[0]++; } } else if (str[i] == 'H') { if (num > 0) { CHO1[1] += num; num = 0;} else { CHO1[1]++;} } else if (str[i] == 'O') { if (num > 0) { CHO1[2] += num; num = 0;} else { CHO1[2]++;} } else { num = str[i] - 48;} } for (int i = b-1 ; i >= a+1; i--) { if (str[i] == 'C') { if (num > 0) { CHO2[0] += num; num = 0; } else { CHO2[0]++; } } else if (str[i] == 'H') { if (num > 0) { CHO2[1] += num; num = 0; } else { CHO2[1]++; } } else if (str[i] == 'O') { if (num > 0) { CHO2[2] += num; num = 0; } else { CHO2[2]++; } } else { num = str[i] - 48; } }
for (int i = str.length()-1; i >= b+1; i--) { if (str[i] == 'C') { if (num > 0) { CHO3[0] += num; num = 0; } else { CHO3[0]++; } } else if (str[i] == 'H') { if (num > 0) { CHO3[1] += num; num = 0; } else { CHO3[1]++; } } else if (str[i] == 'O') { if (num > 0) { CHO3[2] += num; num = 0; } else { CHO3[2]++; } } else { num = str[i] - 48; } } } /* 111 112 113 ... 11 10 각각의 원소에 해당 수를 곱한다음에, 뺴서 0이 나오는지 확인합니다. */ void copy_arr(int a[3], int b[3]) { for (int i = 0; i < 3; i++) { b[i] = a[i]; } } void check() { int C1_store[3], C2_store[3], C3_store[3]; copy_arr(CHO1, C1_store); copy_arr(CHO2, C2_store); copy_arr(CHO3, C3_store); bool isSatisfied = true; for (int i = 0; i < 3; i++) { CHO3[i] *= store[2]; CHO2[i] *= store[1]; CHO1[i] *= store[0]; } for (int i = 0; i < 3; i++) { if (CHO1[i] + CHO2[i] != CHO3[i]) { isSatisfied = false; break; }; } if (isSatisfied) { flag = 1; for (int i = 0; i < 3; i++) { cout << store[i] << " "; } } copy_arr(C1_store, CHO1); copy_arr(C2_store, CHO2); copy_arr(C3_store, CHO3); } void dfs(int depth) { if (flag == 1) return; if (depth == 3) { check(); return; } for (int i = 1; i <= 10; i++) { store[depth] = i; dfs(depth + 1); } } void solve() { dfs(0); } int main() { problemIn(); solve(); return 0; } |
처음 접근을 완전탐색할 아이디어로 짜면 됩니다. 그리고 중복 가능 완전 탐색으로 짜면 됩니다. 그럼 비지트 함수를 넣어주어야 합니다. 그리고 코드의 길이가 중요한 것 아니고, dfs 에서 리턴문을 조심하면 됩니다. |