例题:金块问题

老板有一袋金块(共n块,n是2的幂(n>=2) ),最优秀的员工得到其中最重的一块,最差的员工得到其中最轻的一块。假设有一台比较重量的仪器,请你用最少的比较次数找出最重和最轻的金块。

这个问题其实就是输入n个数,找出最大和最小数的问题。

解决问题的策略

蛮力策略:对金块逐个进行比较查找。(扫描数组一轮,寻找最大和最小的数。)该策略需要进行(n-1)次的比较才能得到Max和min。

分治法(二分法)策略:问题可以简化为在n个数里面寻找最大和最小值。

(1)将数据等分为两组(两组数据的个数可能相差1),目的是分别选取其中的最大(小)值。

(2)递归分解直到每组元素的个数<=2,则可以简单地找到其中的最大(小)值。

(3)回溯时合并子问题的解,在两个子问题的解中大者取大,小者取小,即合并为当前问题的解。

 1 #include<stdio.h>
 2 #include<time.h>
 3 #include<stdlib.h>
 4 int maxMin(int *a,int i,int j,int *max,int *min);
 5 int main()
 6 {
 7     int *a;
 8     int i,n;
 9     int max,min;
10     
11     scanf("%d",&n);
12     a=(int *)malloc(sizeof(int)*n);
13     srand((unsigned int)time(0));
14     for(i=0;i<n;i++) a[i]=rand()%91+10;
15     for(i=0;i<n;i++)
16     {
17         printf("%d ",a[i]);
18         if((i+1)%5==0) printf("\n");
19     }
20     printf("\n\n");
21     maxMin(a,0,n-1,&max,&min);
22     printf("%d %d\n",max,min);/**/
23     return 0;
24 }
25 /*---------------------------------------------------
26 函数名称:maxMin
27 函数功能:在数组a的区间[i,j]范围内寻找一个最大值和一个最小值并通过指针*max和*min返回。
28 -----------------------------------------------------*/
29 int maxMin(int *a,int i,int j,int *max,int *min)
30 {
31     int mid;
32     int lmax,lmin,rmax,rmin;
33     if(j==i) { *max=a[i]; *min=a[i]; return 0;}
34     else if(j-i==1)
35     {
36         if(a[i]>a[j])  {*max=a[i];*min=a[j];return 0;}
37         else  {*max=a[j];*min=a[i];return 0;}
38     }
39     else
40     {
41         mid=i+(j-i)/2;
42         maxMin(a,i,mid,&lmax,&lmin);
43         maxMin(a,mid+1,j,&rmax,&rmin);
44         if(lmax>rmax)   *max=lmax;
45         else   *max=rmax;
46         if(lmin<rmin)     *min=lmin;
47         else   *min=rmin;
48     }
49     return 0;
50 }
二分策略代码

相关文章:

  • 2021-08-21
  • 2021-10-17
  • 2021-08-15
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
猜你喜欢
  • 2022-02-03
  • 2021-07-16
  • 2021-10-27
  • 2022-12-23
  • 2021-07-26
  • 2021-08-30
  • 2022-12-23
相关资源
相似解决方案