v 0. Pasted by slipstak2 as cpp at 2011-01-06 17:27:14 MSK and set expiration to never.

Paste will expire never.

  1. // Меньшиков. Тренировка 12.
  2. // 12F. Химические реакции [chem]
  3. // ibelyaev: 06Jan2011
  4.  
  5. #include <iostream>
  6. #include <cstdio>
  7. #include <map>
  8. #include <string>
  9. #include <string.h>
  10. using namespace std;
  11.  
  12. int n;
  13. typedef map<string,int> form;
  14.  
  15. void ReadSequence(char* &pos, int number, form& formula);
  16.  
  17. inline bool _isEnd(const char* pos)
  18. {
  19.     return !*pos;
  20. }
  21. inline bool _isDigit(const char* pos)
  22. {
  23.     //<число> ::= "1".."9" {"0".."9"}
  24.     if (_isEnd(pos)) return false;
  25.     return '0' <= *pos && *pos <= '9';
  26. }
  27. inline bool _isUpLetter(const char* pos)
  28. {
  29.     //<прописная буква> ::= "A".."Z"
  30.     if (_isEnd(pos)) return false;
  31.     return 'A'<= *pos && *pos <='Z';
  32. }
  33. inline bool _isLwLetter(const char* pos)
  34. {
  35.     //<строчная буква> ::= "a".."z"
  36.     if (_isEnd(pos)) return false;
  37.     return 'a'<= *pos && *pos <='z';
  38. }
  39. inline bool _isChemElemBegin(const char* pos)
  40. {
  41.     if (_isEnd(pos)) return false;
  42.     return _isUpLetter(pos);
  43. }
  44. inline bool _isElemBegin(const char* pos)
  45. {
  46.     if (_isEnd(pos)) return false;
  47.     return _isChemElemBegin(pos) || *pos == '(';
  48. }
  49. inline bool _isSeqBegin(const char* pos)
  50. {
  51.     if (_isEnd(pos)) return false;
  52.     return _isElemBegin(pos);
  53. }
  54. inline bool _isPlusSeq(const char* pos)
  55. {
  56.     if (_isEnd(pos)) return false;
  57.     return *pos == '+';
  58. }
  59. void ReadNumber(char* &pos, int &number)
  60. {
  61.     number = number*10 + (*pos - '0');
  62.     pos++;
  63.     if (!_isEnd(pos) && _isDigit(pos))
  64.         ReadNumber(pos,number);
  65. }
  66. void ReadChemElement(char* &pos, string &chemElement)
  67. {
  68.     //<химический элемент> ::= <прописная буква> [<строчная буква>]
  69.     chemElement += *pos++;
  70.     if (_isLwLetter(pos))
  71.         chemElement += *pos++;
  72. }
  73. void ReadElement(char* &pos, int number, form &formula)
  74. {
  75.     //<элемент> ::= <химический элемент> | "(" <последовательность> ")"
  76.     if (*pos == '(')
  77.     {
  78.         pos++;
  79.         ReadSequence(pos, number, formula);
  80.         pos++;
  81.     }
  82.     else
  83.     {
  84.         string chemElement = "";
  85.         ReadChemElement(pos, chemElement);
  86.         formula[chemElement] += 1;
  87.     }
  88. }
  89. void ReadSequence(char* &pos, int number, form& totalFormula)
  90. {
  91.     //<последовательность> ::= <элемент> [<число>] {<элемент> [<число>]}
  92.     form localFormula;
  93.     while (_isElemBegin(pos)) {
  94.         localFormula.clear();
  95.         ReadElement(pos, number, localFormula);
  96.         int mul = 1;
  97.         if (_isDigit(pos)) {
  98.             mul = 0;
  99.             ReadNumber(pos, mul);
  100.         }
  101.  
  102.         form::iterator it = localFormula.begin();
  103.         for (it; it!= localFormula.end();it++)
  104.             totalFormula[it->first] += it->second * mul;
  105.     }
  106. }
  107. void ReadFormula(char* &pos, form &formula)
  108. {
  109.     //<формула> ::= [<число>] <последовательность> {"+" [<число>] <последовательность>}
  110.     if (_isEnd(pos)) return;
  111.     do
  112.     {
  113.         int number = 1;
  114.         if (_isDigit(pos)){
  115.             number = 0;
  116.             ReadNumber(pos,number);
  117.         }
  118.         form seqFormula;
  119.         if (_isSeqBegin(pos))
  120.             ReadSequence(pos,number,seqFormula);
  121.  
  122.         form::iterator it = seqFormula.begin();
  123.         for (it; it != seqFormula.end(); it++)
  124.             formula[it->first] += it->second * number;
  125.     }
  126.     while (_isPlusSeq(pos++));
  127. }
  128. void ReadFormulaString(string &strFormula, form &formula)
  129. {
  130.     cin>>strFormula;
  131.     char* buf = new char[strFormula.size()+1]; // +1 на нуль символ
  132.     strcpy(buf,strFormula.c_str());
  133.    
  134.     ReadFormula(buf,formula);
  135.  
  136.     buf -= strFormula.size() + 1;
  137.     delete [] buf;
  138. }
  139. void input()
  140. {
  141.     string initStrFormula = "";
  142.     form initFormula;
  143.     ReadFormulaString(initStrFormula, initFormula);
  144.    
  145.     cin>>n;
  146.     for (int i=0;i<n;i++)
  147.     {
  148.         form curFormula;
  149.         string curStrFormula;
  150.         ReadFormulaString(curStrFormula, curFormula);
  151.  
  152.         cout<<initStrFormula;
  153.         if (curFormula == initFormula)
  154.             cout<<"==";
  155.         else
  156.             cout<<"!=";
  157.         cout<<curStrFormula<<endl;
  158.     }
  159. }
  160. int main()
  161. {
  162.     freopen("input.txt","r",stdin);
  163.     freopen("output.txt","w",stdout);
  164.  
  165.     input();
  166.     return 0;
  167. }


Editing is locked.