例题:金块问题
老板有一袋金块(共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 }