韩信走马分油(C语言)

这篇博客探讨了一个有趣的数学问题,即如何仅用3个不同容量的容器,通过倒油操作使得其中一个容器恰好装有特定量的油。这个问题源于法国数学家泊松提出的"泊松分酒",并与我国古代的"韩信走马分油"问题相呼应。文章介绍了问题的背景,给出了编程解决方案,并详细解释了操作规则。通过代码实现,程序能够判断给定的初始状态和目标油量是否能通过操作达到。测试案例表明,程序能够正确输出是否能成功分酒("Y"或"N")。
摘要由CSDN通过智能技术生成

任务描述

泊松是法国数学家、物理学家和力学家。他一生致力科学事业,成果颇多。有许多著名的公式定理以他的名字命名,比如概率论中著名的泊松分布。 有一次闲暇时,他提出过一个有趣的问题,后称为:“泊松分酒”。在我国古代也提出过类似问题,遗憾的是没有进行彻底探索,其中流传较多是:“韩信走马分油”问题。有3个容器,容量分别为12升,8升,5升。其中12升中装满油,另外两个空着。要求你只用3个容器操作,最后使得某个容器中正好有6升油。下面的列表是可能的操作状态记录:
12,0,0
4,8,0
4,3,5
9,3,0
9,0,3
1,8,3
1,6,5
每行3个数据,分别表示12,8,6升容器中的油量,第一行表示初始状态,第二行表示把12升倒入8升容器后的状态,第三行是8升倒入5升,... 当然,同一个题目可能有多种不同的正确操作步骤。

编程要求

根据提示,在右侧编辑器编写代码。
本题目的要求是,由用户输入:各个容器的容量,开始的状态,和要求的目标油量,程序则通过计算输出是否可能分成功-“Y”,“N”。
例如,用户输入:
12,8,5,12,0,0,6
用户输入的前三个数是容器容量(由大到小),接下来三个数是三个容器开始时的油量配置,最后一个数是要求得到的油量(放在哪个容器里得到都可以), 则程序可以输出“Y”

测试说明

平台会对你编写的代码进行测试:

测试输入:12 8 5 12 0 0 6
预期输出:Y

解析:

首先定义一套规则

题目中的瓶子总共有三种,最大的A,中等的B,最小的C,我们规定:

最大的瓶子只能往中等的瓶子倒;(若中等的瓶子为空)

中等的瓶子只能往最小的瓶子倒;(若最小的瓶子不满)

最小的瓶子只能往最大的瓶子倒;(若最小的瓶子已满)

流动时单项的也是唯一的,如果出现了开始的状态则说明容易不可能成功。

#include <stdio.h>
int main(){
    int A, B, C, a, b, c, t;
    scanf("%d", &A);
    scanf("%d", &B);
    scanf("%d", &C);
    scanf("%d", &a);
    scanf("%d", &b);
    scanf("%d", &c);
    scanf("%d", &t);
    int aa = a, bb = b, cc = c;
    while(aa != t && bb != t && cc != t){  // 每一步都加了判断, 因为如果测试集不够严谨,例如3 1 1 3 0 0 1 可能会得出N,因为可以会内部循环,但其实第一步就已经成功了。
        if(bb == 0){
            if(aa >= B){
                aa -= B;
                bb = B;
            }else{
                aa = 0;
                bb = aa;
            }
        }
        if(aa == t || bb == t || cc == t){
            printf("Y\n");
            break;
        }
        if(cc < C){
            int m = C - cc;
            if(bb >= m){
                cc = C;
                bb -= m;
            }else{
                cc += bb;
                bb = 0;
            }
        }
        if(aa == t || bb == t || cc == t){
            printf("Y\n");
            break;
        }
        if(cc == C){
            int m = A - aa;
            if(m >= cc){
                aa += cc;
                cc = 0;
            }else{
                aa += cc;
                cc -= m;
            }
        }
        if(aa == t || bb == t || cc == t){  // 找到了值
            printf("Y\n");
            break;
        }
        if(aa == a && bb == b && cc == c){  // 又回到了原状态 
            printf("N\n");
            break; 
        }
    } 
    return 0;
}

  • 3
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值