如何确定任何给定的连续数组元素的总和是否等于ruby中的给定数字?

时间:2016-06-30 09:24:46

标签: ruby-on-rails arrays ruby ruby-on-rails-3 ruby-on-rails-4

我正在尝试编码问题,要求我打印" YES"如果任何连续数组的总和等于给定的数字和" NO"如果没有。

以下是问题: Prateek希望在他的生日那天给他的N个朋友举办派对,每个朋友的编号从1到N.他的朋友们要求送礼来参加聚会,而不是给他一个。礼物的费用在数组中给出值,其中ith朋友要求礼物,费用为Costi。

但是,Prateek只有X金额花在礼物上,他想邀请他的朋友们在连续的范围内,这样朋友的礼物费用总和将完全等于X.

如果他可以邀请能够满足上述条件的朋友,则打印YES,否则打印NO。

输入: 第一行包含单个整数T,表示测试用例的数量。在每个测试用例中,将出现以下输入: - 下一行包含两个以空格分隔的整数N和X,其中N表示朋友的数量,X表示Prateek可以在礼物上花费的金额。 - 下一行N行包含N个整数,其中第i行包含第i个整数,表示Costi。

输出继电器 输出精确的T行,每行包含相应测试用例的答案。

约束:

1 <= T <= 10
1 <= N , Costi <= 106
1 <= X <= 1012 

示例输入

  1
  5 12
  1
  3
  4
  5
  2

示例输出

YES

解释

在样本输入中,T等于1.因此,在下一行中,给出N和X的值,分别为5和12。在接下来的5行中,你有朋友问的costi。从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

虽然他们已经接受了我的答案,但它没有通过所有的测试用例,因此我不满意。可以有人帮我提供正确,更有效和更优雅的解决方案吗?

2 个答案:

答案 0 :(得分:2)

查看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

或者当您想要返回“是”或“否”时:

array.each_cons(2).any? { |pair| pair.inject(:+) == number } ? 'YES' : 'NO'

答案 1 :(得分:0)

我建议你将答案分成几个部分:

  1. 阅读用户的输入
  2. 确定数组是否包含总和为给定数字的连续子数组
  3. 打印YESNO
  4. 您的代码难以阅读,因为所有这些责任都是相互交织的。第2点至关重要。为了很好地使用第1点和第3点,可以使用一个函数来解决它,它接受一个数字数组和所需的和作为参数,如果有一个带有所需总和的连续子数组,则返回true,否则返回false

    最简单的算法查看所有子阵列,计算它们的总和并与所需的总和进行比较。

    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
    

    startstop标记子阵列的开头和结尾。 Array#inject用于计算子数组的总和。

    我会留下第1点和第3点给你。