CCF CSP 201912-3 化学方程式配平【Python 满分代码】
一、題目
[題目描述]
化學方程式,也稱為化學反應方程式,是用化學式表示化學反應的式子。給出- -組
化學方程式,請你編寫程序判斷每個方程式是否配平(也就是方程式中等號左右兩邊的
元素種類和對應的原子個數是否相同)。
本題給出的化學方程式由大小寫字母、數字和符號(包括等號=、加號+、左圓括
號(和右圓括號))組成,不會出現其他字符(包括空白字符,如空格、制表符等)。化
學方程式的格式與化學課本中的形式基本相同(化學式中表示元素原子個數的下標用.
正常文本,如H2O寫成H20),用自然語言描述如下:
●化學方程式由左右兩個表達式組成,中間用一-個等號=連接,如2H2+02=2H20;
●表達式由若干部分組成,每部分由系數和化學式構成,部分之間用加號+連接,
如2H2+02、2H20;
●系數是整數或空串,如為空串表示系數為1;
●整數由一個或多個數字構成; .
●化學式由若干部分組成,每部分由項和系數構成,部分之間直接連接,如H20、
C02、Ca(0H)2、 Ba3(P04)2;
●項是元素或用左右圓括號括起來的化學式,如H、Ca、(OH)、 (P04);
●元素可以是一個大寫字母,也可以是一個大寫字母跟著一一個小寫字母,如H、0、
Ca。
二、分析
有一天早上突然起來,發現自己想漏了一種情況…遂重新寫了一份,丟進OJ測試后是滿分。
寫CSP的大佬們大多是用的C/C++,百度了一下,python的滿分代碼很少,只找到了一份281ms的代碼,還有一些代碼跟我之前CCF CSP 201912-3 化學方程式 【Python版】這個版本一樣,其實不是超時,是想漏了——官方給的測試點并不全面,需要自己腦中窮舉一波。
這道題我能想到的辦法是用棧來遞歸下降,在python性能有限的情況下,這樣寫出來只需要125ms,我個人還是比較滿意。雖然可能還可以繼續優化,但我還是先貼出來供大家參考,歡迎大家交流指正。
三、代碼部分
# -*- coding: utf-8 -*- """ Spyder EditorThis is a temporary script file. """ ''' 11 Cu+As=Cs+Au 2H2+O2=2H2O H2+Cl2=2NaCl H2+Cl2=2HCl CH4+2O2=CO2+2H2O CaCl2+2AgNO3=Ca(NO3)2+2AgCl 3Ba(OH)2+2H3PO4=6H2O+Ba3(PO4)2 3Ba(OH)2+2H3PO4=Ba3(PO4)2+6H2O 4Zn+10HNO3=4Zn(NO3)2+NH4NO3+3H2O 4Au+8NaCN+2H2O+O2=4Na(Au(CN)2)+4NaOH H2+O2=H2O ''' class E:def __init__(self,in_str):def getNum(i,instr):temp_num=''mylen=len(instr)while i<mylen:if instr[i].isdigit(): temp_num+=(instr[i])i+=1else:breakreturn i,int(temp_num) def apElem(indict,name,num=1):if name in indict:indict[name]+=numelse:indict[name]=numdef disUpper(indict,instr,i):temps=''sub=1mylen=len(instr)temps+=instr[i]i+=1if i>=mylen:apElem(indict,temps,sub)return ielse:if instr[i].islower():temps+=instr[i]i+=1if i>=mylen:apElem(indict,temps,sub)return ielif instr[i].isdigit():i,sub=getNum(i,instr)apElem(indict,temps,sub)return i else:apElem(indict,temps,sub)return ielif instr[i].isdigit():i,sub=getNum(i,instr)apElem(indict,temps,sub)return ielse:apElem(indict,temps,sub)return idef mergeDict(d1,d2):for i in d2.keys():if i in d1:d1[i]+=d2[i]else:d1[i]=d2[i]def updateCoef(dc,coef):for i in dc.keys():dc[i]*=coefdef disBrackets(indict,instr,i):dt={}listb=[]listb.append(i+1)i+=1mylen=len(instr)while i<mylen:if instr[i]=='(':listb.append(i+1)elif instr[i]==')':l=listb.pop()if(not listb):r=its=instr[l:r]disForm(dt,ts)i+=1breaki+=1if(i<mylen and instr[i].isdigit()):i,tempsub=getNum(i,instr)updateCoef(dt,tempsub)mergeDict(indict,dt)return idef disForm(indict,instr):fdict={}mycoef=-1i = 0mylen=len(instr)while i < mylen:if i==0 and instr[i].isdigit():i,mycoef=getNum(i,instr)elif instr[i].isupper():i=disUpper(fdict,instr,i)elif instr[i]=='(':i=disBrackets(fdict,instr,i)else:i+=1if mycoef!=-1:updateCoef(fdict,mycoef)mergeDict(indict,fdict)instr=in_str.split('=')instr_l=instr[0].split('+')instr_r = instr[1].split('+')dictL={}dictR={}for i in instr_l:disForm(dictL,i)for j in instr_r:disForm(dictR,j)if dictL==dictR:print('Y')else:print('N')n=int(input()) for i in range(n):e=E(input())請點個贊吧,拜托了TAT
總結
以上是生活随笔為你收集整理的CCF CSP 201912-3 化学方程式配平【Python 满分代码】的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 移动硬盘安装Kali所碰到到问题
- 下一篇: TensorFlow入门(十-I)tfr