본문 바로가기
Programming/Algorithm

백준 1907 탄소화합물

by OKOK 2018. 3. 8.

/*

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 에서 리턴문을 조심하면 됩니다.