int FindFakeCoin( int ArrayData[], int kb, int ke ) // kb - (子)数组左边界( begin ) // ke - (子)数组右边界( end )

#include<stdio.h>  
#include<stdlib.h>  
#include<time.h>  

#define ARRAY_SIZE 16  
#define TRUE       1  
#define FALSE      0  

int CallTimes = 0;  

// 生成包含 'N' 个硬币重量的数组( 含 1 枚伪币 ), 并返回伪币位置 ...  
int CreateRandomCoinWeightArray( int *p, int N )  
{  
    int i, kt;  
    int TrueCoinWeight, FakeCoinWeight;  
    int IsStop;  

    // 生成随机数种子 ...  
    srand( ( unsigned )time( NULL ) );  

    // 生成随机真币重量值( 在 50 至 100 之间 ) ...  
    TrueCoinWeight = 50 + rand( ) % ( 100 - 50 );  

    // 生成随机伪币位置( 在 0 ~ N-1 之间 ) ...  
    kt = rand( ) % N;  

    // 设置真币重量 ...  
    for( i = 0; i < N; i++ )  
        if ( i != kt )  
            *( p + i ) = TrueCoinWeight;  

    // 生成 1 个比真币略轻的伪币重量值 ...  
    IsStop = FALSE;  
    while( !IsStop )  
    {  
        FakeCoinWeight = 50 + rand( ) % ( 100 - 50 );  
        // 设置满足条件的伪币重量值 ...  
        if ( ( TrueCoinWeight > FakeCoinWeight ) && ( TrueCoinWeight - FakeCoinWeight <= 5 ) )  
        {  
            IsStop = TRUE;  

            *( p + kt ) = FakeCoinWeight;  
        }  
    }  

    // 返回伪币位置 ...  
    return kt;  
}  

// 计算数组中硬币重量和 ...  
int CalcCoinTotalWeight( int ArrayData[], int kb, int ke )  
{  
    int i, TotalWeight = 0;  

    for( i = kb; i <= ke; i++ )  
        TotalWeight += ArrayData[ i ];  

    return TotalWeight;  
}  

// 采用分治法找到伪币( 假定伪币一定存在且只有 1 枚 )  
// kb - (子)数组左边界( begin )  
// ke - (子)数组右边界( end )  
int FindFakeCoin( int ArrayData[], int kb, int ke )  
{  
    int LWeight, RWeight;  
    int flag = 0;  
    CallTimes++;  
    printf( "< 第 %d 次查找 > \n", CallTimes );  
    printf("kb= %d,ke=%d\n",kb,ke);  
    LWeight = CalcCoinTotalWeight(ArrayData,kb,kb+(ke-kb)/2);  
    RWeight = CalcCoinTotalWeight(ArrayData,(kb+(ke-kb)/2) + 1,ke);  
    printf("LWeight = %d\t", LWeight);  
    printf("RWeight = %d\n", RWeight);  
    if(LWeight > RWeight )   
    {  
        if( ke == kb + 1)  
        {  
            return ke;  
        }  
        printf("RF(%d,%d)\n",kb+(ke-kb)/2+ 1,ke);  
        return FindFakeCoin(ArrayData,(kb+(ke-kb)/2) + 1,ke);  
    }  
    else  
    {  
        if(ke == kb +1)  
        {  
            return kb;  
        }  
        printf("LF(%d,%d)\n",kb,kb+(ke-kb)/2);  
        return FindFakeCoin(ArrayData,kb,kb+(ke-kb)/2);  
    }  
}  


int main(void)  
{  
    int ArrayData[ ARRAY_SIZE ];  
    int i, k, FakeCoinPos;  

    // 生成包含 'N' 个硬币重量的数组( 含 1 枚伪币 ), 并返回伪币位置 ...  
    k = CreateRandomCoinWeightArray( ArrayData, ARRAY_SIZE );  

    // 输出随机数组内容 ...  
    printf( "< 生成的硬币重量数组值为( 含 1 枚伪币 ) > : \n" );  
    for( i = 0; i < ARRAY_SIZE; i++ )  
        printf( "[%d]-%d\n", i+1,ArrayData[ i ] );  
    printf( "\n" );  
    printf( "< 第 %d 枚为伪币 > \n", ( k + 1 ) );  
    printf( "\n" );  

    // 采用分治法找到伪币位置 ...  
    FakeCoinPos = FindFakeCoin( ArrayData, 0, ARRAY_SIZE - 1 );  

    printf( "< 找到第 %d 枚为伪币 > \n", ( FakeCoinPos + 1 ) );  
    printf( "\n" );  

    // 等待用户输入任意一键返回 ...  
    system( "PAUSE" );  
    return 0;  
}

 

posted @ 2018-01-31 10:40  sky20080101  阅读(91)  评论(0)    收藏  举报