首页 > 学院 > 开发设计 > 正文

交换两个数组使两个数组和的差最小

2019-11-06 06:26:17
字体:
来源:转载
供稿:网友

今天又看见了这个题目,好像上次是李灾跟我说腾讯面他的时候问了这个问题的。想了半天,在网上也看了半天,发现一个不错的算法,先帖出来:^ ^

 /*    有两个数组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  int  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       return   0 ;111  }112  113  114  int  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       return   0 ;123  }124


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表