将数字写为给定整数的总和

时间:2013-03-27 19:07:42

标签: c++ binary numbers sum combinations

这是问题所在。

将给定数字N作为给定数字的总和,仅使用加法和减法。

以下是一个例子:

N = 20
Integers = 8, 15, 2, 9, 10

20 = 8 + 15 - 2 + 9 - 10.

这是我的想法;

第一个想法是使用蛮力,交替加减。首先,我计算组合的数量和它的2 ^ k(其中k是整数的nubmer),因为我只能交替减去和加号。然后我运行从1到2 ^ k的所有数字,并将其转换为二进制形式。对于任何1我使用加号和任何0我使用减号。您可以通过示例(使用上面的示例)轻松实现。

The number of combinations is: 2^k = 2^5 = 32.
Now I run through all numbers from 1 to 32. 
So i get: 1=00001, that means: -8-15-2-9+10 = -24 This is false so I go on.
2 = 00010, which means: -8-15-2+9-10 = -26. Also false.

这种方法效果很好,但是当整数的数量太大时,它需要的时间太长。

这是我在C ++中的代码:

#include <iostream>
#include <cmath>
using namespace std;
int convertToBinary(int number) {
    int remainder;
    int binNumber = 0;
    int i = 1;
    while(number!=0)
    {
        remainder=number%2;
        binNumber=binNumber + (i*remainder);
        number=number/2;
        i=i*10;
    }
    return binNumber;
}
int main()
{
    int N, numberOfIntegers, Combinations, Binary, Remainder, Sum;
    cin >> N >> numberOfIntegers;
    int Integers[numberOfIntegers];
    for(int i = 0; i<numberOfIntegers; i++)
    {
        cin >>Integers[i];
    }
    Combinations = pow(2.00, numberOfIntegers);
    for(int i = Combinations-1; i>=Combinations/2; i--) // I use half of the combinations, because 10100 will compute the same sum as 01011, but in with opposite sign.
    {
        Sum = 0;
        Binary = convertToBinary(i);
        for(int j = 0; Binary!=0; j++)
        {
            Remainder = Binary%10;
            Binary = Binary/10;
            if(Remainder==1)
            {
                Sum += Integers[numberOfIntegers-1-j];
            }
            else
            {
                Sum -= Integers[numberOfIntegers-1-j];
            }
        }
        if(N == abs(Sum))
        {
            Binary = convertToBinary(i);
            for(int j = 0; Binary!=0; j++)
            {
                Remainder = Binary%10;
                Binary = Binary/10;
                if(Sum>0)
                {
                    if(Remainder==1)
                    {
                        cout << "+" << Integers[numberOfIntegers-1-j];
                    }
                    else
                    {
                        cout << "-" << Integers[numberOfIntegers-1-j];
                    }
                }
                else
                {
                    if(Remainder==1)
                    {
                        cout << "-" << Integers[numberOfIntegers-1-j];
                    }
                    else
                    {
                        cout << "+" << Integers[numberOfIntegers-1-j];
                    }
                }
            }
            break;
        }
    }
    return 0;
}

3 个答案:

答案 0 :(得分:0)

由于这是典型的家庭作业,我不打算给出完整的答案。但请考虑一下:

K = +a[1] - a[2] - a[3] + a[4]

可以改写为

a[0] = K
a[0] + a[2] + a[3] = a[1] + a[4]

您现在双方都有正常的子集和。

答案 1 :(得分:0)

所以你担心的是你的复杂性。

让我们分析一下可以进行哪些优化。

给出[n]和目标值T中的n个数字;

确定加法和减法的一个组合给你T;

所以Sigma(m * a [k])= T其中(m =( - 1或1)且0> = k> = n-1)

这只是意味着..

它可以写成

(数组中某些数字的总和)=(数组中剩余数字的总和)+ T

就像你的情况一样..

8 + 15-2 + 9-10 = 20可写为

8 + 15 + 9 = 20 + 10 + 2

所有数字的总和,包括target = 64 //我们可以校准那个..:)

所以它的一半是32

如果进一步写为20+(somthing)= 32 在这种情况下,这是12(2 + 10)。

您的问题可以简化为查找数组中的数字,在这种情况下总和为

所以现在你的问题可以减少,因为找到总和为k的数字组合(你可以按照上面描述的k = 12进行计算。)其复杂度为O(log(n))n作为数组的大小,请记住,您必须对数组进行排序并使用基于二进制搜索的算法来获取O(log(n))。

因为复杂性可以从O(2 ^ n)到O((N + 1)logN)进行排序。

答案 2 :(得分:0)

这会使用您提供的静态输入,并且我使用core java

编写
  public static void main(String[] args) {

    System.out.println("Enter number");

    Scanner sc = new Scanner(System.in);

    int total = 0;

    while (sc.hasNext()) {


        int[] array = new int[5] ;

        for(int m=0;m<array.length;m++){
            array[m] = sc.nextInt();
        }

         int res =array[0];
            for(int i=0;i<array.length-1;i++){

                    if((array[i]%2)==1){
                            res = res - array[i+1];
                    }
                    else{
                    res =res+array[i+1];
                    }
            }
            System.out.println(res);
    }
}