题目
题目是图片,比较坑,建议大家去原网址看。
思路
将化学方程式按照等号先拆成两部分,用一个函数分别处理两部分,返回一个包含所有元素及其数量的一个字典,对比两个字典内容是否一致,如果一致打印Y,否则打印N。
解决问题的核心是处理方程式的函数,这里用的方法是,先将方程式的某一侧按照+分割开,在进一步处理这分割开的一小部分。对于每一部分,先分离出开头的数字,最后得到的元素的数量都要乘以该值。余下的部分进行进一步的处理,假设用一个deal函数处理余下的部分。
deal函数是一个递归的函数,该函数首先找大写字母,之后找小写字母和数字。如果中途发现了括号,则去掉最外层的括号后进行递归处理,否则向字典中修改对应元素的值。deal函数最终返回一个字典。
一些问题
上面那样做又个小问题,就是嵌套括号括号是直接去掉最外层的括号,而不是去掉配对的括号。这样简单的拆括号肯定是有问题的,因此我这样做最后一个测试点无法通过,只拿80分。但是这道题太累人了,我现在不想改了,等其它时候有空再改。
代码
def deal_x(x): i = 0 rlt = {} while i<len(x): name = '' num = '' k_name = '' k_num = '' tmp_rlt = {} #get the name if i<len(x) and x[i].isupper(): name+=x[i] i+=1 while i<len(x) and x[i].islower(): name+=x[i] i+=1 if i < len(x) and x[i]=='(': i+=1 while i<len(x) and x[i]!=')': k_name += x[i] i+=1 i+=1 while i<len(x) and x[i].isdigit(): k_num+=x[i] i+=1 if k_num=='': k_num = '1' tmp_rlt = deal_x(k_name) for j in tmp_rlt: if j in rlt: rlt[j]+=int(k_num)*tmp_rlt[j] else: rlt[j] = int(k_num)*tmp_rlt[j] #get the num while i<len(x) and x[i].isdigit(): num+=x[i] i+=1 if num=='': num = '1' if name in rlt: rlt[name]+=int(num) else: rlt[name]=int(num) return rlt def mul_num(num): i = 0 rlt = '' while i<len(num): if num[i].isdigit(): rlt+=num[i] else: break i+=1 if rlt=='': return (1,i) else: return (int(rlt),i) def process(x): ''' 该函数用于返回一个字典 字典中包含了每种元素的名称和数量 ''' rlt = {} x = x.split('+') for i in range(len(x)): mul,pos = mul_num(x[i]) x[i] = x[i][pos:] tmp_rlt = deal_x(x[i]) for j in tmp_rlt: if j in rlt: rlt[j]+=mul*tmp_rlt[j] else: rlt[j] = mul*tmp_rlt[j] if '' in rlt: del rlt[''] return rlt n = int(input()) for i in range(n): left,right = input().split('=') rlt_left = process(left) rlt_right = process(right) if rlt_left==rlt_right: print('Y') else: print('N')
一些感想
CSP的第三题真的蛋疼,花式折磨人,要么是字符串处理,要么是题目长达一页多,消磨人的耐心。我觉得真的挺没劲的,但是没办法,为了分数,得拼一把。