n年前传说中华为面试题(8分钟写出代码)

有两个数组a,b,大小都为n,数组元素的值任意,无序;
要求:通过交换a,b中的元素,使数组a元素的和与数组b元素的和之间的差最小
 
思路:
用二重循环把a中的每个元素和b中的每个元素逐个“尝试交换”,
如果是差值变小就维持交换,否则就交换回去,也就是不交换,
每有一次交换,“尝试交换”的二重循环就重新从头开始,
直到没有任何交换使差值变小为止。
这种方法不是很简洁,但的确是可行的。
前边贴出代码的算法,有过一次交换后,循环没有从头开始,所以是错误的。例如a[1]和b[j]交换后,b中的元素改变了,不能再保证a[0]和b[ i ]交换不会使差值变小,这时循环必须从头开始。
 
实现代码:
  1. #include <stdio.h>
  2. #include <math.h>

  3. #define N 10

  4. void ary_init(int a[], int b[]){ //初始化数组
  5.     int i;
  6.     for (i=0; i<N; i++){
  7.         a[i] = rand()%10000;
  8.     }
  9.     for (i=0; i<N; i++){
  10.         b[i] = rand()%100;
  11.     }
  12.     return;
  13. }
  14. long sum(int a[]){ //数组求和
  15.     int i;
  16.     int s;
  17.     for (s=0,i=0; i<N; i++){
  18.         s += a[i];
  19.     }
  20.     return s;
  21. }

  22. void change(int *a, int *b){ //数组元素交换
  23.     int tmp;
  24.     tmp = *a;
  25.     *= *b;
  26.     *= tmp;
  27.     return;
  28. }

  29. void prt_ary(int a[], int b[]){ //列印两数组元素及各自元素和
  30.     int i;
  31.     for(i=0; i<N; i++){
  32.         printf("%5d ", a[i]);
  33.     }
  34.     printf("\n");
  35.     for(i=0; i<N; i++){
  36.         printf("%5d ", b[i]);
  37.     }
  38.     printf("\n");
  39.     printf("%d\n", sum(a));
  40.     printf("%d\n", sum(b));
  41. }
  42. int slove(int a[], int b[]){
  43.     int i;
  44.     int j;
  45.     int is_swap = 0;//是否修交换过数据标志
  46.     int ab_diff;

  47.     ab_diff = abs(sum(a)-sum(b));
  48.     for (i=0; i<N; i++){
  49.         for (j=0; j<N; j++){
  50.             change(a+i, b+j);
  51.             if (abs(sum(a)-sum(b)) < ab_diff){//判断是否需要交换元素
  52.                 is_swap = 1; //置位交换标志
  53.                 ab_diff = abs(sum(a)-sum(b)); //更新差值
  54.             }
  55.             else{
  56.                 change(b+j, a+i);//不交换

  57.             }
  58.         }
  59.     }
  60.     return is_swap;
  61. }
  62. int main(){

  63.     int a[N];
  64.     int b[N];

  65.     ary_init(a,b);//数组元素初始化
  66.     prt_ary(a, b);//列印当前数组状态
  67.     while (slove(a, b));//处理数组
  68.     prt_ary(a, b);//列印交换后数组状态
  69.     getch();
  70. }

本文根据cu精华贴整理而来,在此对代码贡献者表示感谢:

http://bbs.chinaunix.net/viewthread.php?tid=855126&extra=page%3D1%26amp%3Bfilter%3Ddigest

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值