如何将一个数字分成两个,每个数字都在一个范围内?

时间:2016-12-01 15:08:12

标签: split integer sum range

在尝试提问时,我被要求将数字'n'分成2个部分,每个部分都在给定范围内(包括)。

显然可以有多个解决方案,只需要一个。

示例 - n = 5 and Range = 2 to 4

       Solutions would be (2,3) (3,2)

头脑很容易,但无法获得快速逻辑。 谢谢

语言 - C ++

4 个答案:

答案 0 :(得分:1)

#include<bits/stdc++.h>

using namespace std;

int main(){

int l,r,s;

cin>>l>>r>>s;    //here l & r are range & s is sum that we want to split

if(2 * r < s){

cout<<0<<endl;

return 0;

}

int start,end;

start = s - l;

if(start > r){

start -= r;

start += l;

}

end = s-start;

int count = abs(end - start) + 1;

cout<<count<<endl;

return 0;

}

 

答案 1 :(得分:0)

对于每个部分“在给定范围内(包括)”,n = 5 and Range = 2 to 4的解决方案为(2,3), (3,2)

最简单的解决方案就是这样:

for i = range_min to range_max:
    if range_min <= n - i <= range_max:
        print (i, n-i)

更新。更深入的分析:

a = range_min
b = range_max

a <= i <= b

a <= n - i <= b
a - n <= -i <= b - n
-a + n >= i >= -b + n
n - b <= i <= n - a

max(a, n-b) <= i <= min(b, n-a)

for i = max(a, n-b) to min(b, n-a):
    print (i, n-i)

没有什么比这更有效了,因为无论如何你需要遍历所有匹配对至少来打印它们,这里只有 打印。

更新2.只有一对(如果存在)和C ++:

#include <iostream>
#include <algorithm> // min, max
using namespace std;

int main()
{
    int n, a, b;
    cin >> n >> a >> b;
    int lo = max(a, n-b);
    int hi = min(b, n-a);
    if (lo <= hi) {
        cout << "(" << lo << ", " << n - lo << ")" << endl;
    } else {
        cout << "nope" << endl;
    }
    return 0;
}

答案 2 :(得分:0)

您尚未指定要使用的语言,因此这是使用JavaScript的一个非常基本的实现:

var n = 5;
for (var i = 0; i < n-1; i++) {
  var first = i + 1;
  var second = n-i-1;
  console.log('(' + first + ',' + second + ')' + ' ' + '(' + second + ',' + first + ')' );
}

希望有所帮助!

答案 3 :(得分:0)

我建议枚举而不是拆分:

  1. 验证输入:to >= fromvalue >= 2 * fromvalue <= 2 * to
  2. value - tofrom
  3. 开始
  4. 返回[from..to]范围内的两个部分
  5. 样本C#6.0解决方案

    public static IEnumerable<Tuple<int, int>> Ranges(int value, int from, int to) {
      if (to < from) // empty range
        yield break;
      else if (value < 2 * from || value > 2 * to) // value is too small or too big
        yield break;
    
      // start either from left border or from minumum possible value within the range
      int start = value - to >= from ? value - to : from;
    
      // both i and value - i should be in [to..from] range
      for (int i = start; i <= to && value - i >= from; ++i) 
        yield return new Tuple<int, int>(i, value - i); // (i, value - i) pair
    }
    

    测试:

    var result = Ranges(5, 2, 4)
      .Select(range => $"({range.Item1},{range.Item2})");
    
    Console.Write(string.Join(" ", result));
    

    结果:

    (3,4) (4,3)