8枚硬币和n枚硬币问题

这篇博客探讨了如何使用C语言解决两种硬币找零问题:8枚硬币和任意数量(n枚)硬币。通过代码展示了解决方案,并提供了完整的代码实现和运行结果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

8枚硬币:

void Compare(int a[], int i, int j , int k){//i :较重的  j :较轻的  k:正确的
        if(a[i] > a[k]){
           printf("第%d 个硬币是假币,偏重\n" , i + 1);
        }if(a[j] < a[k]){
            printf("第%d 个硬币是假币,偏轻\n" , j + 1);
        }
}

void Coin1(int a[])
{
    int i;

    int add1 = 0, add2 = 0;      //每组的重量
     for(i = 0; i < 3 ; i++){
        add1 += a[i];
    }

    for(i = 3; i < 6 ; i++){
        add2 += a[i];
    }



    if(add1 == add2){ //假币在第三组

        if(a[6] > a[7]){
            Compare(a, 6, 7, 0);
        }else{
            Compare(a, 7, 6, 0);
        }
    }

    if(add1 > add2){  //真币在第三组
       if(a[0] + a[3] > a[1] + a[4]){
        Compare(a, 0, 4, 1);
       }else if(a[0] + a[3] == a[1] + a[4]){
           Compare(a, 2, 5, 0);
       }else{
       Compare(a, 1, 3, 0);

       }
    }else{
        if(a[0] + a[3] > a[1] + a[4]){
        Compare(a, 3, 1, 0);
       }else if(a[0] + a[3] == a[1] + a[4]){
           Compare(a, 5, 2, 0);
       }else{
       Compare(a, 4, 0, 1);

       }
    }
}

n枚硬币:

//得到真币下标
int getRel(int coin[], int m, int n){
    if(n - m + 1 <= 2){
        printf("无解");
        return -1;
    }else{
        if(coin[1] == coin[0])
            return 0;
        else
            return 2;
    }
}
void getCoin(int n, int coin[]){
    int i = 0, s0, s1, s2;

    srand((int)time(NULL));
    while(1){
        s0 = rand() % 10; //真币的重量
        if(s0 != 0)
            break;
    }

    while(1){
        coin[i] = s0;
        i++;
        if(i == n)
            break;
    }
    s1 = rand() % n; //生成假币的下标

     while(1){
        s2 = rand() % 10; //假币的重量
        if(s2 != 0 && s2 != s0)
            break;
    }
    i = 0;
    while(1){
        if(i == s1){
            coin[i] = s2;
            break;
        }
        i++;
    }

}
//硬币总重量 下标从 m到n
int Sum_Coin(int coin[], int m , int n){
    int res = 0;
    int i;
    if(m > n)
        return 0;
    for(i = m; i <= n; i++){
        res += coin[i];
    }
    return res;
}
//将硬币分为4组  1组有(N-(N%3))/3 2组有(N-(N%3))/3 3组有(N-(N%3))/3 4组有 N%3
int Coin2(int coin[], int m, int n, int relCoin){
    int vary = n - m + 1;  //硬币数量的数量

    if(vary == 1){
        return m;
    }
    if(vary == 2){ //只剩下两个点时 如果 第一个点 和rel相等  就返回第二个点
        if(Sum_Coin(coin, m, m) == Sum_Coin(coin, relCoin, relCoin))
            return n;
        else
            return m;
    }

    int restCoin = vary % 3;  // 分组4的硬币数量
  //  int vary2 = (vary - restCoin) / 3;  //第1,2,3组里的硬币数量

  int vary2 = vary/3;
    //第一组和第二组比较
    if(Sum_Coin(coin, m, m + vary2 - 1) == Sum_Coin(coin, m+vary2, m+vary2*2 - 1)){
        //第一组和第三组比较
        if(Sum_Coin(coin, m, m + vary2 - 1) == Sum_Coin(coin, m+vary2*2, m+vary2*3 - 1))
            Coin2(coin, n - restCoin+1, n, relCoin);//相等的话,假币在第四组里
        else
            Coin2(coin, m+vary2*2, m+vary-1, relCoin);//不相等的话,假币在第三组里

    }else{//第一堆不等于第二堆 在第一堆或第二堆里
        if(Sum_Coin(coin, m, m+vary2-1) == Sum_Coin(coin, m+vary2*2, m+vary2*3-1))
            //第一堆合第三堆相等  假硬币在第二堆里
            Coin2(coin, m + vary2, m + vary2 * 2 - 1, relCoin);
        else//不相等 假币在第一堆里;
            Coin2(coin, m, m + vary2 - 1, relCoin);
    }

}

打印:

void printCoin(int coin[], int n){
    int i = 0;

    for(i = 0; i < n; i++){
        printf("coin[ %d ] = %d\t", i + 1, coin[i]);
    }
    printf("\n");
}

完整代码:

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


void Compare(int a[], int i, int j , int k){//i :较重的  j :较轻的  k:正确的
        if(a[i] > a[k]){
           printf("第%d 个硬币是假币,偏重\n" , i + 1);
        }if(a[j] < a[k]){
            printf("第%d 个硬币是假币,偏轻\n" , j + 1);
        }
}

void Coin1(int a[])
{
    int i;

    int add1 = 0, add2 = 0;      //每组的重量
     for(i = 0; i < 3 ; i++){
        add1 += a[i];
    }

    for(i = 3; i < 6 ; i++){
        add2 += a[i];
    }



    if(add1 == add2){ //假币在第三组

        if(a[6] > a[7]){
            Compare(a, 6, 7, 0);
        }else{
            Compare(a, 7, 6, 0);
        }
    }

    if(add1 > add2){  //真币在第三组
       if(a[0] + a[3] > a[1] + a[4]){
        Compare(a, 0, 4, 1);
       }else if(a[0] + a[3] == a[1] + a[4]){
           Compare(a, 2, 5, 0);
       }else{
       Compare(a, 1, 3, 0);

       }
    }else{
        if(a[0] + a[3] > a[1] + a[4]){
        Compare(a, 3, 1, 0);
       }else if(a[0] + a[3] == a[1] + a[4]){
           Compare(a, 5, 2, 0);
       }else{
       Compare(a, 4, 0, 1);

       }
    }
}


//比较n枚硬币

//得到真币下标
int getRel(int coin[], int m, int n){
    if(n - m + 1 <= 2){
        printf("无解");
        return -1;
    }else{
        if(coin[1] == coin[0])
            return 0;
        else
            return 2;
    }
}
void getCoin(int n, int coin[]){
    int i = 0, s0, s1, s2;

    srand((int)time(NULL));
    while(1){
        s0 = rand() % 10; //真币的重量
        if(s0 != 0)
            break;
    }

    while(1){
        coin[i] = s0;
        i++;
        if(i == n)
            break;
    }
    s1 = rand() % n; //生成假币的下标

     while(1){
        s2 = rand() % 10; //假币的重量
        if(s2 != 0 && s2 != s0)
            break;
    }
    i = 0;
    while(1){
        if(i == s1){
            coin[i] = s2;
            break;
        }
        i++;
    }

}
//硬币总重量 下标从 m到n
int Sum_Coin(int coin[], int m , int n){
    int res = 0;
    int i;
    if(m > n)
        return 0;
    for(i = m; i <= n; i++){
        res += coin[i];
    }
    return res;
}
//将硬币分为4组  1组有(N-(N%3))/3 2组有(N-(N%3))/3 3组有(N-(N%3))/3 4组有 N%3
int Coin2(int coin[], int m, int n, int relCoin){
    int vary = n - m + 1;  //硬币数量的数量

    if(vary == 1){
        return m;
    }
    if(vary == 2){ //只剩下两个点时 如果 第一个点 和rel相等  就返回第二个点
        if(Sum_Coin(coin, m, m) == Sum_Coin(coin, relCoin, relCoin))
            return n;
        else
            return m;
    }

    int restCoin = vary % 3;  // 分组4的硬币数量
  //  int vary2 = (vary - restCoin) / 3;  //第1,2,3组里的硬币数量

  int vary2 = vary/3;
    //第一组和第二组比较
    if(Sum_Coin(coin, m, m + vary2 - 1) == Sum_Coin(coin, m+vary2, m+vary2*2 - 1)){
        //第一组和第三组比较
        if(Sum_Coin(coin, m, m + vary2 - 1) == Sum_Coin(coin, m+vary2*2, m+vary2*3 - 1))
            Coin2(coin, n - restCoin+1, n, relCoin);//相等的话,假币在第四组里
        else
            Coin2(coin, m+vary2*2, m+vary-1, relCoin);//不相等的话,假币在第三组里

    }else{//第一堆不等于第二堆 在第一堆或第二堆里
        if(Sum_Coin(coin, m, m+vary2-1) == Sum_Coin(coin, m+vary2*2, m+vary2*3-1))
            //第一堆合第三堆相等  假硬币在第二堆里
            Coin2(coin, m + vary2, m + vary2 * 2 - 1, relCoin);
        else//不相等 假币在第一堆里;
            Coin2(coin, m, m + vary2 - 1, relCoin);
    }

}

void printCoin(int coin[], int n){
    int i = 0;

    for(i = 0; i < n; i++){
        printf("coin[ %d ] = %d\t", i + 1, coin[i]);
    }
    printf("\n");
}
int main()
{

    printf("-----------------------八枚硬币-------------------\n");
    int a[8];
    getCoin(8, a);
    printCoin(a, 8);
    Coin1(a);

    printf("----------------------n枚硬币----------------------\n");

    int n;



         printf("\n几枚硬币??");
        scanf("%d", &n);

        int coin[n];
      //  int i, m;

        getCoin(n, coin);
     /*  printf("输入硬币重量:\n");
       for(i = 0; i < n; i++){
            scanf("%d", &m);
        coin[i] = m;
       }*/
        printCoin(coin, n);
        int relcoin = getRel(coin, 0, n);
       printf("rel = %d", relcoin);
        int fakeCoin = Coin2(coin, 0, n - 1, relcoin);

        printf("第%d枚硬币是假币", fakeCoin + 1);
         if(fakeCoin != 0){
            if(coin[fakeCoin] > coin[0])
                printf(" 假币偏重");
            else
                printf(" 假币偏轻");
        }else{
            if(coin[fakeCoin] > coin[1])
                printf(" 假币偏重");
            else
                printf(" 假币偏轻");
        }


    return 0;
}

运行结果:


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值