免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: forrestgang
打印 上一主题 下一主题

华为面试题(8分钟写出代码) [复制链接]

论坛徽章:
0
451 [报告]
发表于 2014-10-21 16:17 |只看该作者
难度大, 不过不考虑效率, 可以先整体排序, 然后再平均分到两个数组。   然后根据0-n对等比较,再排!

论坛徽章:
0
452 [报告]
发表于 2014-10-25 12:26 |只看该作者
如果允许O(n^2)的空间复杂度,可以这样做。
1. 计算数组A的和减去数组B的和,得到两数组和的差
2. 用第一个数组A的每一个元素减去数组B中的每一个元素的值,保存在n阶矩阵中,矩阵标号为两个数组的互换标号。
3. 将问题转化为求n阶矩阵和与第一步计算出的差值的最接近的值。这个问题比较容易求解。

算法复杂度为O(n^2)。

论坛徽章:
0
453 [报告]
发表于 2014-10-25 12:27 |只看该作者
回复 449# 路上风声


    这个思路有问题,每次都取差值也不能保证和是最小的。

论坛徽章:
1
寅虎
日期:2014-11-30 21:25:54
454 [报告]
发表于 2014-11-30 19:45 |只看该作者
回复 443# lovai

DP算法,dp[j]表示i个数的和为j的方案数,如果用dp额外再保存具体的方案,就容易得出最终的算法。

  1. #include <stdio.h>
  2. #include <string.h>

  3. #define MOD     1000
  4. #define N       10

  5. int C[N*2];
  6. int dp[N+1][MOD*N*2];

  7. int main()
  8. {
  9.         int i,j,k,n,sum;
  10.         while(~scanf("%d",&n)&&n)
  11.         {
  12.                 memset(dp,0,sizeof(dp));
  13.                 for(i=0,sum=0;i<n*2;i++)
  14.                 {
  15.                         scanf("%d",&C[i]);
  16.                         sum+=C[i];
  17.                 }
  18.                 dp[0][0]=1;
  19.                 for(i=0;i<2*n;i++)
  20.                         for(j=sum/2;j>=C[i];j--)
  21.                                 for(k=n;k>0;k--)
  22.                                         if(dp[k-1][j-C[i]])
  23.                                                 dp[k][j]++;
  24.                 for(i=sum/2;i>0;i--)
  25.                         if(dp[n][i])
  26.                                 break;
  27.                 printf("%d %d\n",i,sum-i);
  28.         }
  29. }
复制代码

论坛徽章:
59
2015年亚洲杯之约旦
日期:2015-01-27 21:27:392015年亚洲杯之日本
日期:2015-02-06 22:09:41拜羊年徽章
日期:2015-03-03 16:15:432015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:50:282015元宵节徽章
日期:2015-03-06 15:50:392015年亚洲杯之阿联酋
日期:2015-03-19 17:39:302015年亚洲杯之中国
日期:2015-03-23 18:52:23巳蛇
日期:2014-12-14 22:44:03双子座
日期:2014-12-10 21:39:16处女座
日期:2014-12-02 08:03:17天蝎座
日期:2014-07-21 19:08:47
455 [报告]
发表于 2014-11-30 20:40 |只看该作者
我倒, 这个问题这么难么? 这么久没人给出正确的答案?
答案是做一个 m+n的数组, 求平均值e,
然后不就是从m+n个元素中求 m个元素和最接近于e的背包问题了么?

论坛徽章:
0
456 [报告]
发表于 2015-01-10 14:56 |只看该作者
数组A和数组B,

两个数组的数字进行排序,排序后数组C,和为sum
c[0]放入a[0],sum = sum-c[0],
如果c[0]>sum则c中剩余元素从大到小依次填充到b中,再剩余元素填充到a中
反之,则将c[1]填充到b[0],sum = sum-b[0]

重复上面的步骤,注意此时应将c[3]填充到b[1]

论坛徽章:
0
457 [报告]
发表于 2015-03-09 16:45 |只看该作者
8分钟...

论坛徽章:
0
458 [报告]
发表于 2015-04-19 23:06 |只看该作者
PP

论坛徽章:
0
459 [报告]
发表于 2015-04-24 16:28 |只看该作者
本帖最后由 zhangbo357 于 2015-04-24 16:33 编辑

大致思想就是将两个数组a b的差放到另一个数组c,再对c数组求和,再用该和减c数组中的元素,如果减了之后绝对值变小了就将对应位置的a b数组元素交换,直到最后,就这么简单
测试了下 貌似正确
  1. #include <stdio.h>
  2. #include <math.h>

  3. int main()
  4. {
  5.     int a[5] = {6,5,8,4,9};
  6.     int b[5] = {5,8,5,1,6};
  7.     int c[5] = {0};
  8.     int sum1 = 0,sum2 = 0,suma = 0,sumb = 0;
  9.     int i;
  10.     for(i = 0;i < 5;i++)
  11.     {
  12.         c[i] = a[i]-b[i];
  13.         sum1 +=c[i];
  14.     }
  15.     printf("%d\n",sum1);
  16.     for( i = 0;i < 5;i++)
  17.     {
  18.         sum2 = abs(sum1);
  19.         if(abs(sum1 - c[i]*2) < sum2)
  20.         {
  21.             sum1 -= c[i]*2;
  22.             
  23.             a[i] ^= b[i];
  24.             b[i] ^= a[i];
  25.             a[i] ^= b[i];
  26.         }
  27.         suma += a[i];
  28.         sumb += b[i];
  29.         printf("%d %d\n",a[i],b[i]);
  30.     }
  31.    
  32.     printf("%d\n",suma-sumb);
  33.    
  34.     return 0;
  35. }
复制代码

论坛徽章:
0
460 [报告]
发表于 2015-04-24 16:38 |只看该作者
我觉得题目还是有歧义,我理解的是对应位置相交换,而不是任意位置相交换回复 458# zhangbo357


   
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP