这道题卡了我几个小时,一开始用广搜,调死我了都调不出来,后来想起来跟之前做过的一个题目有点像——HJ41。我那道题题解链接在这:https://www.nowcoder.com/discuss/442297072662872064
后来放弃广搜,直接用set一把梭,结果一会就梭出来了哈哈哈
简单捋一下思路:
设输入存在a中
因为是分成两个数组,使得他们的和相等。
所以这里可以求得他们的和应该是sum(a)/2
这里暗含一个条件就是sum(a)是偶数(因为奇数不能由两个相等的整数得到)——光是这一点就可以过好几个样例了
而两个数组分别是含5和含3的(假设有5或3)
这里任选一个,比如含5的,设含5的数组叫b
现在要做的就是往b里面加数字,得到不同的和,
把所有的可能用集合s存起来,检查sum(a)/2在不在s中,在则输出true,退出程序
如果所有可能都枚举完成还没找到,则输出false
代码如下:
#Tips: #创建空集只能使用set(),{}是用来创建空字典的,但是创建非空集合可以使用{} #思路: #求得输入的总和sum,其一半half就是分成的两个数组各自应该达成的总和 #本问题就变成了,在一堆数字里面找一些数字满足和为特定值half #这就跟41题很像了,只是集合s的初始数据是5的倍数的总和 #用广搜只过了20/26,实在调不出来了 #用set一把梭一下,写完发现这个比广搜简单多了 n=int(input()) a=[int(i) for i in input().split()] b=[] half=sum(a)//2#用整除避免得到浮点数 #特判 if sum(a)%2==1:#和为奇数,不可能分成功 print("false") exit() if sum(a)==0 and not(5 in a and 3 in a):#和为0,且3和5不同时存在,直接分成一组 print("true") exit() #选择5的倍数,放入b for i in a: if i%5==0: b.append(i) #将b中元素从a中剔除掉 for i in b: a.remove(i) s=set()#用于存储所有组合的和 #先把5的倍数全部加起来,放进s s.add(sum(b)) #再算a中剩下的 for i in a: for j in list(s): if i%3!=0: s.add(i+j) if half in s: print("true") exit() print("false")
最后放上我过了20/26的广搜代码,如果有大佬看出来我写的为啥过不了,顺便告诉我一声就好了,拜谢~
#Tips: #对于广搜,搜到答案之后就直接exit退出整个程序, #不要用return,return只是结束当前这一层,其他的搜索还是会执行 #思路: #广度优先搜索 #求得输入的总和sum,其一半half就是分成的两个数组各自应该达成的总和 #本问题就变成了,在一堆数字里面找一些数字满足和为特定值 #把5的倍数挑出来形成一个组b,再往b中加数据,直到等于half,如果超过half,说明当前分组失败 n=int(input()) a=[int(i) for i in input().split()] b=[] half=sum(a)//2#用整除避免得到浮点数 #特判 if sum(a)%2==1:#和为奇数,不可能分成功 print("false") exit() if sum(a)==0 and not(5 in a and 3 in a):#和为0,且3和5不同时存在,直接分成一组 print("true") exit() #选择5的倍数,放入b for i in a: if i%5==0: b.append(i) #将b中元素从a中剔除掉 for i in b: a.remove(i) def check(a,b): if sum(b)==half: print("true") exit() elif sum(b)<half:#不够,继续加数字 for i in a: if i%3!=0:#3的倍数不能往里加 c=a[:] c.remove(i)#注意不要直接操作a if len(c)==0:#如果搜到最后一个元素了,就不能继续往更深层搜索了,进下一层check的时候c已经空了,遍历的时候要出问题 if sum(b)+i==half: print("true") exit() else: return check(c,b+[i])#广搜 else:#b的sum超过了一半,不用往下搜索了 return check(a,b) print("false")