Paste will expire never.
- // Меньшиков. Тренировка 12.
- // 12F. Химические реакции [chem]
- // ibelyaev: 06Jan2011
- #include <iostream>
- #include <cstdio>
- #include <map>
- #include <string>
- #include <string.h>
- using namespace std;
- int n;
- typedef map<string,int> form;
- void ReadSequence(char* &pos, int number, form& formula);
- inline bool _isEnd(const char* pos)
- {
- return !*pos;
- }
- inline bool _isDigit(const char* pos)
- {
- //<число> ::= "1".."9" {"0".."9"}
- if (_isEnd(pos)) return false;
- return '0' <= *pos && *pos <= '9';
- }
- inline bool _isUpLetter(const char* pos)
- {
- //<прописная буква> ::= "A".."Z"
- if (_isEnd(pos)) return false;
- return 'A'<= *pos && *pos <='Z';
- }
- inline bool _isLwLetter(const char* pos)
- {
- //<строчная буква> ::= "a".."z"
- if (_isEnd(pos)) return false;
- return 'a'<= *pos && *pos <='z';
- }
- inline bool _isChemElemBegin(const char* pos)
- {
- if (_isEnd(pos)) return false;
- return _isUpLetter(pos);
- }
- inline bool _isElemBegin(const char* pos)
- {
- if (_isEnd(pos)) return false;
- return _isChemElemBegin(pos) || *pos == '(';
- }
- inline bool _isSeqBegin(const char* pos)
- {
- if (_isEnd(pos)) return false;
- return _isElemBegin(pos);
- }
- inline bool _isPlusSeq(const char* pos)
- {
- if (_isEnd(pos)) return false;
- return *pos == '+';
- }
- void ReadNumber(char* &pos, int &number)
- {
- number = number*10 + (*pos - '0');
- pos++;
- if (!_isEnd(pos) && _isDigit(pos))
- ReadNumber(pos,number);
- }
- void ReadChemElement(char* &pos, string &chemElement)
- {
- //<химический элемент> ::= <прописная буква> [<строчная буква>]
- chemElement += *pos++;
- if (_isLwLetter(pos))
- chemElement += *pos++;
- }
- void ReadElement(char* &pos, int number, form &formula)
- {
- //<элемент> ::= <химический элемент> | "(" <последовательность> ")"
- if (*pos == '(')
- {
- pos++;
- ReadSequence(pos, number, formula);
- pos++;
- }
- else
- {
- string chemElement = "";
- ReadChemElement(pos, chemElement);
- formula[chemElement] += 1;
- }
- }
- void ReadSequence(char* &pos, int number, form& totalFormula)
- {
- //<последовательность> ::= <элемент> [<число>] {<элемент> [<число>]}
- form localFormula;
- while (_isElemBegin(pos)) {
- localFormula.clear();
- ReadElement(pos, number, localFormula);
- int mul = 1;
- if (_isDigit(pos)) {
- mul = 0;
- ReadNumber(pos, mul);
- }
- form::iterator it = localFormula.begin();
- for (it; it!= localFormula.end();it++)
- totalFormula[it->first] += it->second * mul;
- }
- }
- void ReadFormula(char* &pos, form &formula)
- {
- //<формула> ::= [<число>] <последовательность> {"+" [<число>] <последовательность>}
- if (_isEnd(pos)) return;
- do
- {
- int number = 1;
- if (_isDigit(pos)){
- number = 0;
- ReadNumber(pos,number);
- }
- form seqFormula;
- if (_isSeqBegin(pos))
- ReadSequence(pos,number,seqFormula);
- form::iterator it = seqFormula.begin();
- for (it; it != seqFormula.end(); it++)
- formula[it->first] += it->second * number;
- }
- while (_isPlusSeq(pos++));
- }
- void ReadFormulaString(string &strFormula, form &formula)
- {
- cin>>strFormula;
- char* buf = new char[strFormula.size()+1]; // +1 на нуль символ
- strcpy(buf,strFormula.c_str());
- ReadFormula(buf,formula);
- buf -= strFormula.size() + 1;
- delete [] buf;
- }
- void input()
- {
- string initStrFormula = "";
- form initFormula;
- ReadFormulaString(initStrFormula, initFormula);
- cin>>n;
- for (int i=0;i<n;i++)
- {
- form curFormula;
- string curStrFormula;
- ReadFormulaString(curStrFormula, curFormula);
- cout<<initStrFormula;
- if (curFormula == initFormula)
- cout<<"==";
- else
- cout<<"!=";
- cout<<curStrFormula<<endl;
- }
- }
- int main()
- {
- freopen("input.txt","r",stdin);
- freopen("output.txt","w",stdout);
- input();
- return 0;
- }
Editing is locked.