C语言趣味编程之平分七筐鱼

目录
  • 题目描述
  • 分析
  • 代码实现
  • 运行结果
  • 网上参考

题目描述

甲、乙、丙三位渔夫出海打鱼,他们随船带了21只箩筐。当晚返航时,他们发现有7筐装满了鱼,还有7筐装了半筐鱼,另外7筐则是空的,由于他们没有秤,只好通过目测认为7个满筐鱼的重量是相等的,7个半筐鱼的重量是相等的。在不将鱼倒出来的前提下,怎样将鱼平分为3份?

分析

这题还有两个隐形要求:三个人分得的箩筐数量相同(7只);列出所有的平分方法。

我的思路(参照网上他人方法)

首先,所有的鱼所占的箩筐数为7+7*0.5=10.5只(7只满筐和7只半筐),将它们平分成3份,那么每个人就能分到3.5只装满鱼的箩筐(例如3只满筐和1只半筐或者1只满筐5只半筐等等)。

我们可以先遍历出甲分到的装满鱼的箩筐数,然后再遍历出乙分到的装满鱼的箩筐数,丙的满筐鱼箩筐数则为7-甲乙的满筐鱼的箩筐数之和。由于最后每个人都能分到3.5筐鱼,所以他们最多可分配3只装满鱼的箩筐。

确定完他们的满筐鱼箩筐数之后,接着遍历甲乙分到的半筐鱼箩筐数,丙分到的半筐鱼箩筐数则等于7-甲乙的半筐鱼的箩筐数之和。由于目前他们分到的满筐鱼的箩筐数为整数,而最终他们都必须分得3.5筐鱼,所以每个人至少要分到一只装有半筐鱼的箩筐,且一定是奇数只。

在分配完半筐鱼的箩筐后,如果每个人所分到的鱼的箩筐数为3.5(其实判断甲乙即可),那么说明该分配方式符合条件。

最后,每个人空筐的箩筐数=7-该人的满筐鱼箩筐数-该人的半筐鱼箩筐数。

我的代码还有一些可优化的地方(可以删去一些无效的循环次数),在网上参考部分有一个很不错的例子(我的思路和代码就参考了该例子)。

代码实现

#include <stdio.h>

int main()
{
    //甲乙丙分得的不同类型箩筐数量
    int fish_nums[3][3] = {0};
    int i = 0, j = 0, k = 0, m = 0, n = 0;

    //甲分满箩筐,最大3筐
    for(i = 0; i <= 3; i++)
    {
        fish_nums[0][0] = i; //甲分得满箩筐数
        //乙分满箩筐,最大三筐
        for(j = 0; j <= 3; j++)
        {
            fish_nums[1][0] = j;         //乙分得满箩筐数
            fish_nums[2][0] = 7 - i - j; //丙分得满箩筐数
            if(fish_nums[2][0] > 3)
                continue;                //超过3.5框

            //甲分奇数个半箩筐,最少1个,最多5个(其他人也要分)
            for(k = 1; k <= 5; k+=2)
            {
                if(fish_nums[0][0] + 0.5 * k == 3.5)
                    break;
            }
            fish_nums[0][1] = k;         //甲分得半箩筐数

            //乙分奇数个半箩筐,最少1个,最多5个(其他人也要分)
            for(m = 1; m <= 5; m+=2)     //乙分奇数个半箩筐
            {
                if(fish_nums[1][0] + 0.5 * m == 3.5)
                    break;
            }
            fish_nums[1][1] = m;         //乙分得半箩筐数
            fish_nums[2][1] = 7 - k - m; //丙分得半箩筐数

            //甲分得空箩筐数
            fish_nums[0][2] = 7 - fish_nums[0][0] - fish_nums[0][1];
            //乙分得空箩筐数
            fish_nums[1][2] = 7 - fish_nums[1][0] - fish_nums[1][1];
            //丙分得空箩筐数
            fish_nums[2][2] = 7 - fish_nums[2][0] - fish_nums[2][1];

            //打印匹配的结果
            for(n = 0; n < 3; n++)
            {
                if(n == 0)
                    printf("甲——");
                else if(n == 1)
                    printf("乙——");
                else printf("丙——");
                printf("满筐:%d,半筐:%d,空筐:%d\n", fish_nums[n][0],\
                        fish_nums[n][1], fish_nums[n][2]);
                if(n == 2)
                    printf("-------------------------------------\n");
            }
        }
    }
    return 0;
}

运行结果

由于我考虑了针对甲乙丙三个不同的人的分法,所以最后结果有6个,如果不考虑三个人的身份,那么分法还需要除以3,即只有2种(具体代码可以参考下文的网上参考部分)

网上参考

原文链接:http://c.biancheng.net/cpp/html/3370.html

核心思路

  • (1) 数组的每行或每列的元素之和都为7。
  • (2) 对数组的行来说,满筐数加半筐数=3.5。
  • (3) 每个人所得的满筐数不能超过3筐。
  • (4) 每个人都必须至少有1个半筐,且半筐数一定为奇数。
#include<stdio.h>
int a[3][3], count;
int main()
{
    int i, j, k, m, n, flag;
    printf("It exists possible distribtion plans:\n");
    for(i=0; i<=3; i++)  /*试探第一个人满筐a[0][0]的值,满筐数不能>3*/
    {
        a[0][0]=i;
        for(j=i; j<=7-i&&j<=3; j++)  /*试探第二个人满筐a[1][0]的值,满筐数不能>3*/
        {
            a[1][0]=j;
            if((a[2][0]=7-j-a[0][0])>3)
                continue;  /*第三个人满筐数不能>3*/
            if(a[2][0]<a[1][0])
                break;  /*要求后一个人分的满筐数大于等于前一个人,以排除重复情况*/
            for(k=1; k<=5; k+=2)  /*试探半筐a[0][1]的值,半筐数为奇数*/
            {
                a[0][1]=k;
                for(m=1; m<7-k; m+=2)  /*试探半筐a[1][1]的值,半筐数为奇数*/
                {
                    a[1][1]=m;
                    a[2][1]=7-k-m;
                    /*判断每个人分到的鱼是 3.5筐,flag为满足题意的标记变量*/
                    for(flag=1,n=0; flag&&n<3; n++)
                        if(a[n][0]+a[n][1]<7&&a[n][0]*2+a[n][1] == 7)
                            a[n][2]=7-a[n][0]-a[n][1];  /*计算应得到的空筐数量*/
                        else
                            flag=0;  /*不符合题意则置标记为0*/
                    if(flag)
                    {
                        ++count;
                        printf("No.%d Full basket Semi-basket Empty\n", count);
                        for(n=0; n<3; n++)
                            printf(" fisher %c: %d %d %d\n",'A'+n, a[n][0], a[n][1], a[n][2]);
                    }
                }
            }
        }
    }
    return 0;
}

原文结果:

以上所述是小编给大家介绍的C语言趣味编程之平分七筐鱼,希望对大家有所帮助。在此也非常感谢大家对我们网站的支持!

(0)

相关推荐

  • C语言算法--有序查找(折半查找/二分查找)

    目录 题目 解法一: 挨个遍历 方法二:折半查找/二分查找(仅适用于有序查找) 总结 题目 首先我们来把题目瞅一眼: 在一个有序数组中查找具体的某个数字n. 编写int binary_search (int x, int v[], int n); 功能:在v [0] <= v [1] <= v [2] <= -. <= v [n-1]的数组中查找x. 题目大概的意思就是说这是一串有序的数组,我们编写代码完成以下功能:如果输入的数字在数组中,就输出找到了并输出下标,如果输入的数字不在

  • C语言算法的定义及分析详解

    目录 算法的定义 算法和程序的区别 算法 程序 算法的性质 算法的表示 算法的分析 分析原则 常用的复杂性函数 算法分析基本法则 非递归算法: 总结 算法的定义 算法是一系列良定义的计算步骤 算法和程序的区别 算法 算法是指解决问题的一种方法或一个过程. 算法是若干指令的有穷序列,满足性质: 1.输入:有外部提供的量作为算法的输入. 2.输出:算法产生至少一个量作为输出. 3.确定性:组成算法的每条指令是清晰,无歧义的. 4.有限性:算法中每条指令的执行次数是有限的,执行每条指令的时间也是有限的

  • 详解约瑟夫环问题及其相关的C语言算法实现

    约瑟夫环问题 N个人围成一圈顺序编号,从1号开始按1.2.3......顺序报数,报p者退出圈外,其余的人再从1.2.3开始报数,报p的人再退出圈外,以此类推.   请按退出顺序输出每个退出人的原序号 算法思想 用数学归纳法递推. 无论是用链表实现还是用数组实现都有一个共同点:要模拟整个游戏过程,不仅程序写起来比较烦,而且时间复杂度高达O(nm),若nm非常大,无法在短时间内计算出结果.我们注意到原问题仅仅是要求出最后的胜利者的序号,而不是要读者模拟整个过程.因此如果要追求效率,就要打破常规,实

  • C语言趣味编程之平分七筐鱼

    目录 题目描述 分析 代码实现 运行结果 网上参考 题目描述 甲.乙.丙三位渔夫出海打鱼,他们随船带了21只箩筐.当晚返航时,他们发现有7筐装满了鱼,还有7筐装了半筐鱼,另外7筐则是空的,由于他们没有秤,只好通过目测认为7个满筐鱼的重量是相等的,7个半筐鱼的重量是相等的.在不将鱼倒出来的前提下,怎样将鱼平分为3份? 分析 这题还有两个隐形要求:三个人分得的箩筐数量相同(7只):列出所有的平分方法. 我的思路(参照网上他人方法) 首先,所有的鱼所占的箩筐数为7+7*0.5=10.5只(7只满筐和7

  • C语言趣味编程之水仙花数

    目录 题目描述 分析 代码实现 运行结果 题目描述 求出所有的水仙花数 分析 百度百科:水仙花数(Narcissistic number)也被称为超完全数字不变数(pluperfect digital invariant, PPDI).自恋数.自幂数.阿姆斯壮数或阿姆斯特朗数(Armstrong number),水仙花数是指一个 3 位数,它的每个位上的数字的 3次幂之和等于它本身.例如:13 + 53+ 33 = 153. 判断一个数是否为水仙花数,可以先将该数的所有位都取出并存入数组,最后代

  • Java语言面向对象编程思想之类与对象实例详解

    在初学者学Java的时候,面向对象很难让人搞懂,那么今天小编就来为大家把这个思想来为大家用极为简单的方法理解吧. 首先我们来简单的阐述面向对象的思想. 面向对象: 官方的语言很抽象,我们把官方的解释和定义抛开.想想,自己有什么,对!!我们自己有手脚眼口鼻等一系列的器官.来把自己所具有的器官就可以看作我们的属性,自己是不是可以喜怒哀乐和嬉笑怒骂,这些是不是我们的行为,那么自己的具有的属性加自己有的行为就称为一个对象. 注意!!我们自己,一个个体是一个对象,因为,你是你,我是我,我们虽然有相同的,但

  • Go语言Web编程实现Get和Post请求发送与解析的方法详解

    本文实例讲述了Go语言Web编程实现Get和Post请求发送与解析的方法.分享给大家供大家参考,具体如下: 这是一篇入门文章,通过一个简单的例子介绍Golang的Web编程主要用到的技术. 文章结构包括: 1. Client-Get 请求 2. Client-Post 请求 3. Server 处理 Get 和 Post 数据 在数据的封装中,我们部分采用了json,因而本文也涉及到Golang中json的编码和解码. 一.Client-Get 复制代码 代码如下: package main i

  • c语言网络编程-标准步骤(比较简单)

    c语言网络编程-标准步骤,真的很简单啊 server.c 复制代码 代码如下: #include <stdio.h>#include <stdlib.h>#include <string.h>#include <netdb.h>#include <netinet/in.h>#include <sys/types.h>#include <sys/socket.h>#include <arpa/inet.h> #d

  • java并发编程专题(七)----(JUC)ReadWriteLock的用法

    前面我们已经分析过JUC包里面的Lock锁,ReentrantLock锁和semaphore信号量机制.Lock锁实现了比synchronized更灵活的锁机制,Reentrantlock是Lock的实现类,是一种可重入锁,都是每次只有一次线程对资源进行处理:semaphore实现了多个线程同时对一个资源的访问:今天我们要讲的ReadWriteLock锁将实现另外一种很重要的功能:读写分离锁. 假设你的程序中涉及到对一些共享资源的读和写操作,且写操作没有读操作那么频繁.在没有写操作的时候,两个线

  • Go语言并发编程之互斥锁Mutex和读写锁RWMutex

    目录 一.互斥锁Mutex 1.Mutex介绍 2.Mutex使用实例 二.读写锁RWMutex 1.RWMutex介绍 2.RWMutex使用实例 在并发编程中,多个Goroutine访问同一块内存资源时可能会出现竞态条件,我们需要在临界区中使用适当的同步操作来以避免竞态条件.Go 语言中提供了很多同步工具,本文将介绍互斥锁Mutex和读写锁RWMutex的使用方法. 一.互斥锁Mutex 1.Mutex介绍 Go 语言的同步工具主要由 sync 包提供,互斥锁 (Mutex) 与读写锁 (R

  • Go语言并发编程 sync.Once

    sync.Once用于保证某个动作只被执行一次,可用于单例模式中,比如初始化配置.我们知道init()函数也只会执行一次,不过它是在main()函数之前执行,如果想要在代码执行过程中只运行某个动作一次,可以使用sync.Once,下面来介绍一下它的使用方法. 先来看下面的代码: package main import ( "fmt" "sync" ) func main() { var num = 6 var once sync.Once add_one := fu

  • Go语言并发编程 互斥锁详情

    目录 1.互斥锁Mutex 1.1 Mutex介绍 1.2 Mutex使用实例 2.读写锁RWMutex 2.1 RWMutex介绍 2.2 RWMutex使用实例 1.互斥锁Mutex 1.1 Mutex介绍 Go 语言的同步工具主要由 sync 包提供,互斥锁 (Mutex) 与读写锁 (RWMutex) 就是sync 包中的方法. 互斥锁可以用来保护一个临界区,保证同一时刻只有一个 goroutine 处于该临界区内.主要包括锁定(Lock方法)和解锁(Unlock方法)两个操作,首先对进

  • 详解C语言面向对象编程中的封装

    目录 前言 一.面向对象基本概念 什么是对象? 对象与类 面向对象的编程方式 二.C语言实现面向对象 面向对象的三大特征 面向对象之封装 简介 代码实现–基础版 代码实现-进阶版 总结 前言 面向对象是一种思维方式,基本上用什么语言都是可以实现的.C语言的编程方式一般是面向过程的,但是也是可以实现面向对象的.对象是什么?什么又是面向对象?面向对象的三大特性又怎么实现,且听我细细道来. 一.面向对象基本概念 什么是对象? 此对象非彼对象,虽然有时候此对象又可以是你脑袋中的对象,那让我们从我们误解的

随机推荐