题目
题目是图片,比较坑,建议大家去原网址看。
思路
将化学方程式按照等号先拆成两部分,用一个函数分别处理两部分,返回一个包含所有元素及其数量的一个字典,对比两个字典内容是否一致,如果一致打印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的第三题真的蛋疼,花式折磨人,要么是字符串处理,要么是题目长达一页多,消磨人的耐心。我觉得真的挺没劲的,但是没办法,为了分数,得拼一把。

京公网安备 11010502036488号