zoukankan      html  css  js  c++  java
  • 【100题】第三十二 数组、规划

    一,题目:有两个序列a,b,大小都为n,序列元素的值任意整数,无序;要求:通过交换a,b中的元素,使[序列a元素的和]与[序列b元素的和]之间的差最小。
          例如:  
                   var   a=[100 ,99 ,98 ,1 ,2 ,3];       var  b=[1, 2, 3, 4, 5, 40];
          有两个序列a,b,大小都为n,序列元素的值任意整数,无序;
          要求:通过交换a,b中的元素,使[序列a元素的和]与[序列b元素的和]之间的差最小。

    二,分析

    第一种算法:
       当前数组a和数组b的和之差为
       A = sum(a) - sum(b)

       a的第i个元素和b的第j个元素交换后,a和b的和之差为
       A' = sum(a) - a[i] + b[j] - (sum(b)- b[j] + a[i])
              = sum(a) - sum(b) - 2 (a[i] - b[j])
              = A - 2 (a[i] - b[j])

        设x= a[i] - b[j]
        |A| - |A'| = |A| - |A-2x|

        假设A> 0,
        当x在(0,A)之间时,做这样的交换才能使得交换后的a和b的和之差变小,
    x越接近A/2效果越好,
       如果找不到在(0,A)之间的x,则当前的a和b就是答案。

        所以算法大概如下:
       在a和b中寻找使得x在(0,A)之间并且最接近A/2的i和j,交换相应的i和j元素,
    重新计算A后,重复前面的步骤直至找不到(0,A)之间的x为止。

    第二种算法:
             1.将两序列合并为一个序列,并排序,为序列Source
             2.拿出最大元素Big,次大的元素Small
             3.在余下的序列S[:-2]进行平分,得到序列max,min
             4.将Small加到max序列,将Big加大min序列,重新计算新序列和,和大的为max,小的为min。

    a={1,2,3,4,5} b={6,7,8,9,10}

    s={1,2,3,4,5,6,7,8,9,10}

    a={1,3,6,7,10}

    b={2,4,5,8,9}

    三,第一种解法源码

    #include <iostream>
    using namespace std;
    class RunClass
    {
       public:
             void BalanceArray( int array1[],  int array2[],int n1,int n2);
       private:
              int Sum(int array[],int n);
    };
    
    void RunClass::BalanceArray(int array1[], int array2[],int n1,int n2)
    {
    
         if (n1 != n2)
              return;
         int *array=new int[n1];
         if (Sum(array1,n1) < Sum(array2,n2))
         {
    
               array= array1;
               array1 = array2;
               array2 = array;
         }
                bool ifCycle = true;
                int length = n1;
                while (ifCycle)
                {
                   ifCycle = false;     
                    for (int i = 0; i < length; i++)
                    {
                        for (int j = 0; j < length; j++)
                        {
                            int itemValue = array1[i] - array2[j];
                            int sumValue = Sum(array1,n1) - Sum(array2,n2);
                            if (itemValue < sumValue && itemValue > 0)
                            {
                                ifCycle = true;
                                int item = array1[i];
                                array1[i] = array2[j];
                                array2[j] = item;
                            }
                        }
                    }
                }
    }
    
    int RunClass::Sum(int array[],int n)
    {
           int sum = 0;
    
           for (int i = 0; i < n; i++)
            {
              sum += array[i];
            }
           return sum;
     }
    
    int main()
    {
       int array1[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 90, 0, 0, 100 };
       int array2[] = { -1, -2, -100, -3, 99, -222, -2, -3, -5, -88, 11, 12, 13 };
    
       RunClass  a;
       a.BalanceArray(array1, array2,13,13);
    
       for(int i=0;i<13;i++)
           cout<<array1[i]<<"  ";
       cout<<endl;
    
       for(int i=0;i<13;i++)
           cout<<array2[i]<<"  ";
       cout<<endl;
    
       return 0;
    
     }


  • 相关阅读:
    Understanding about Baire Category Theorem
    Isometric embedding of metric space
    Convergence theorems for measurable functions
    Mindmap for "Principles of boundary element methods"
    Various formulations of Maxwell equations
    Existence and uniqueness theorems for variational problems
    Kernels and image sets for an operator and its dual
    [loj6498]农民
    [luogu3781]切树游戏
    [atAGC051B]Three Coins
  • 原文地址:https://www.cnblogs.com/secbook/p/2655021.html
Copyright © 2011-2022 走看看