我正在尝试一个编码问题,要求我打印"YES",如果任何连续数组数的总和等于给定的数字和"NO",如果没有。
问题如下:Prateek想在他的生日那天为他的N个朋友举办一个聚会,每个朋友都从1到N编号。他的朋友们要求一个礼物来参加聚会,而不是给他一个礼物。礼物的成本在数组Value中给出,其中好友请求的礼物的成本为Costi。
但是,Prateek只有X钱可以用来买礼物,他想邀请在连续范围内的朋友,这样这些朋友的礼物费用总和正好等于X。
如果他可以邀请满足上述条件的朋友,则打印YES,否则打印NO。
输入:第一行包含一个整数T,表示测试用例的数量。在每个测试用例中,将出现以下输入:—下一行包含两个空格分隔的整数N和X,其中N代表朋友的数量,X代表Prateek可以花在礼物上的金额。—下N行包含N个整数,其中第1行包含1个整数,代表Costi。
输出输出T行,每一行都包含对应测试用例的答案。
约束条件包括:1 <= T <= 10
1 <= N , Costi <= 106
1 <= X <= 1012
示例输入
1
5 12
1
3
4
5
2
的示例输出 是的
解释在样本输入中,T = 1。因此,在下一行中,N和X的值分别为5和12。在接下来的5行中,你有朋友问你的问题。因为从2到4(包括)的朋友的礼物值为{3,4,5},并且它们的总和等于12——即给定的x值。所以,答案是肯定的。
我的解决方案在这里
b = Array.new
a = Array.new
t = gets.to_i
if t >= 0 && t <= 10
t.times do
n, x = gets.chomp.split.map(&:to_i)
n.times do
a << gets.to_i
end
(1..a.length).each do |num|
a.each_cons(num).each do |pair|
if pair.inject(:+) == x
b << "YES"
else
b << "NO"
end
end
end
if b.include?("YES")
puts "YES"
else
puts "NO"
end
end
end
虽然他们接受了我的答案,但它并没有通过所有的测试用例,因此我不满意。有人能给我一个正确的,更有效的,优雅的解决方案吗?
看看each_cons
:
array = [1,2,3,4,5]
number = 5
array.each_cons(2) { |pair| puts 'YES' if pair.inject(:+) == number }
#=> 'YES'
number = 10
array.each_cons(2) { |pair| puts 'YES' if pair.inject(:+) == number }
#=> nil
或者当您想要返回'YES'或'NO'时:
array.each_cons(2).any? { |pair| pair.inject(:+) == number } ? 'YES' : 'NO'
我建议你把答案分成几个部分:
- 读取用户输入
- 确定一个数组是否包含一个连续的子数组,该子数组之和为给定的数字
- 打印
YES
或NO
。
你的代码很难阅读,因为所有这些职责是相互交织在一起的。第二点至关重要。为了很好地处理第1点和第3点,它可以用一个函数来解决,该函数接受数字数组和所需的和作为参数,如果有一个具有所需和和false
的连续子数组,则返回true
。
最简单的算法查看所有子数组,计算它们的和,并与期望的和进行比较。
def consecutive_sum?(array, sum)
(0...array.size).each do |start|
(start...array.size).each do |stop|
return true if array[start..stop].inject(&:+) == sum
end
end
false
end
start
和stop
标记子数组的开始和结束。Array#inject
用于计算子数组的和。