交換兩個數組使兩個數組和的差最小(轉載)

/*

    有兩個數組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爲止。

*/

把算法大概實現了一下,程序如下:

  1int test(float a[], float b[], int n)
  2{
  3   float sumA, sumB; //sumA爲數組a總和,sumB爲數組b總和
  4   float sum_diff, num_diff; //sum_diff爲a,b總和差, num_diff爲a,b中各選的兩個數之差
  5   float temp1, temp2;    //temp1爲 每輪sum_diff/2, temp2爲每輪所選兩個數之差於temp1最接近的那個
  6   int i, j;
  7   float temp; //用於對調a,b間數
  8   int tempi, tempj;    //每輪所選兩個數之差於temp1最接近的那組數
  9    unsigned int flag_sum =0, flag_num =0//flag_sum爲1, sumA大於sumB; flag_num爲1, 此輪存在兩個數之差小於sum_diff
10
11
12       
13
14   while(1){
15
16       //算出a,b數組和
17        sumA =0;
18        sumB=0;
19       for(i=0;i< n;i++)
20        {
21            sumA+= a[i];
22            sumB+= b[i];
23        }
24
25       if(sumA>= sumB){
26            sum_diff= sumA - sumB;
27            flag_sum=1;
28        }
29       else
30            sum_diff= sumB - sumA;   
31   
32        temp1= sum_diff/2;
33        temp2= temp1;
34        tempi=0;
35        tempj=0;   
36   
37       //找出a,b間差值最接近sum_diff/2的那一對數
38       if(flag_sum==1){   //sumA > sumB
39           for(i=0; i < n; i++)
40               for(j=0; j < n; j++)
41               
42                   if(a[i]> b[j]){
43                        num_diff= a[i] - b[j];
44                       if(num_diff< sum_diff){
45                            flag_num=1;
46                           if(num_diff>= temp1){
47                               if(num_diff-temp1< temp2){
48                                    temp2= num_diff-temp1;
49                                    tempi= i;
50                                    tempj= j;
51                                }
52                            }
53                           else{
54                               if(temp1- num_diff < temp2){
55                                    temp2= temp1 - num_diff;
56                                    tempi= i;
57                                    tempj= j;
58                                }
59                            }
60                        }
61                    }
62        }
63       else{
64           for(i=0; i < n; i++)
65               for(j=0; j < n; j++)
66               
67                   if(a[i]< b[j]){
68                        num_diff= b[j] - a[i];
69                       if(num_diff< sum_diff){
70                            flag_num=1;
71                           if(num_diff>= temp1){
72                               if(num_diff-temp1< temp2){
73                                    temp2= num_diff-temp1;
74                                    tempi= i;
75                                    tempj= j;
76                                }
77                            }
78                           else{
79                               if(temp1- num_diff < temp2){
80                                    temp2= temp1 - num_diff;
81                                    tempi= i;
82                                    tempj= j;
83                                }
84                            }
85                        }
86                    }
87        }
88
89       if(flag_num==0)
90           break;
91
92        temp= a[tempi];
93        a[tempi]= b[tempj];
94        b[tempj]= temp;
95   
96        flag_num=0;
97        flag_sum=0;
98    }
99       
100   for(i=0; i < n;i++)
101        printf("%f\t",a[i]);
102
103    printf("\n");
104
105   for(i=0; i < n;i++)
106        printf("%f\t",b[i]);
107
108    printf("\n");   
109   
110   return0;
111}
112
113
114int main(int argc, char*argv[])
115{
116
117   float a[3]= {4,5,12};
118   float b[3]= {1,2,3};
119
120    test(a, b,3);
121
122   return0;
123}
124

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章