算法设计与分析 | 分而治之算法 | 金块问题

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_36292543/article/details/83963469

目录

题目描述 

问题分析

代码编写

打印结果


题目描述 

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

问题分析

对于一般思路:通过一个函数Max进行n-1次比较来找到最重的金块,然后再从余下的n-2个金块中用同样的方法Min函数找到最轻的金块,这样,比较的总次数为2n-3。 
对于 分治法:(分治法是将问题划分为若干个子问题,然后通过求解子问题的解来获得原问题的解)

先考虑n≤2的情况 
①当n=1时,即只有一块金子,此时无需进行比较 
②当n=2时,此时只需比较一次就可以判断出最重和最轻的金块

对于n>2的情况 
第一步,将金子平均分成两份A,B 
第二步,分别在A,B中找到最重和最轻的金块 
第三步,再次比较A中最重的金子和B中最重的金子,A中最轻的金子和B中最轻的金块

时间复杂度:

若n=0 
T(n)=0
若n=1 
T(n)=1
若n>2 
T(n)=2T(n/2)+2 
通过Master定理可得为O(n)
代码的总体设计逻辑就是将n个金块分成等量的两份A,B,然后再将A分成等量的两份(若A中金块的数量n1>2),然后再次等量分,通过一次次的划分,找到符合n=1或n=2的情况,然后直接进行比较,总体来说就是不断的递归

代码编写

#include<stdio.h> 
//比较重量大小的函数
int min(int x,int y)
{    
    if(x<y)     
        return x;  
    else     
        return y; 
}

int max(int x,int y)
{    
    if(x>y)      
        return x;  
    else     
        return y; 
}

int Find_min(int A[],int left,int right)  //这里是寻找最轻的金块的函数
{   
    int la,ma,ra;
    if(left==right)    //对于n=1的情况
    {
        int min;
        min=A[right];
        return min;
    }
    if(right-left==1)    //对于n=2的情况
    {
        la=A[left];
        ra=A[right];
        return(min(la,ra));
    }
    if(right-left>1)   //对于n>2的情况
    {
        ma=(left+right)/2;      
        la=Find_min(A,left,ma); 
        ra=Find_min(A,ma,right);
        return(min(la,ra));     
    }       
}   
int Find_max(int A[],int left,int right)  //寻找最重金块的函数
{   
    int la,ma,ra;   
    if(left==right)
    {    
        int max;    
        max=A[right];    
        return max;   
    }    
    if(right-left==1)    
    {    
        la=A[left];    
        ra=A[right];    
        return(max(la,ra));     
    }      
    if(right-left>1)
    {       
        ma=(left+right)/2;      
        la=Find_max(A,left,ma);      
        ra=Find_max(A,ma,right);      
        return(max(la,ra));     
    }       
}   
int main()
{    
    int A[100];  
    int n;     
    int min;
    int max;   
    printf("请输入金块数目:");   
    scanf("%d",&n);   
    printf("请输入各金块的重量:");   
    for(int i=0;i<n;i++)   
        scanf("%d",&A[i]);    
    printf("最重的金块:");   
    max=Find_max(A,0,n-1);    
    printf("%d",max);      
    printf("\n");   
    printf("最轻的金块:");   
    min=Find_min(A,0,n-1);     
    printf("%d",min); 
    printf("\n"); 
    return 0;
}

打印结果

猜你喜欢

转载自blog.csdn.net/qq_36292543/article/details/83963469