colorfulshark

Linux Kernel Developer(WindRiver System)

蓝桥杯 泊松分酒 数学分析 解题报告

 
    泊松是法国数学家、物理学家和力学家。他一生致力科学事业,成果颇多。有许多著名的公式定理以他的名字命名,比如概率论中著名的泊松分布。
 
    有一次闲暇时,他提出过一个有趣的问题,后称为:“泊松分酒”。在我国古代也提出过类似问题,遗憾的是没有进行彻底探索,其中流传较多是:“韩信走马分油”问题。
 
    有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升,...
 
    当然,同一个题目可能有多种不同的正确操作步骤。
 
    本题目的要求是,请你编写程序,由用户输入:各个容器的容量,开始的状态,和要求的目标油量,程序则通过计算输出一种实现的步骤(不需要找到所有可能的方法)。如果没有可能实现,则输出:“不可能”。
 
    例如,用户输入:
12,8,5,12,0,0,6
 
    用户输入的前三个数是容器容量(由大到小),接下来三个数是三个容器开始时的油量配置,最后一个数是要求得到的油量(放在哪个容器里得到都可以)
 
    则程序可以输出(答案不唯一,只验证操作可行性):
12,0,0
4,8,0
4,3,5
9,3,0
9,0,3
1,8,3
1,6,5
 
    每一行表示一个操作过程中的油量状态。
 
   注意:
 
    请仔细调试!您的程序只有能运行出正确结果的时候才有机会得分!
     
 

本题参考了网上找到的一个分析思路:


首先定义一套规则

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


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

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

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


这样就会产生一个循环,并且可以理解为已最小瓶子的容量为度量进行A->B->C的循环,B作为中间体,只有空了之后才会从A中调入,这样就可以保证每一次的倒入都是独一无二的,而且可以包容所有的情况并且符合倒入规则。


在规定了这样一个单向流动的过程之后,就可以通过模拟的方法来计算了,以为每一步都会是独一无二的,所以每一次倒完之后,直接输出就可以了,在倒的时候要注意量的大小,不要变成负的了。

另外,针对不可能的情况,我们可以这样想,如果当到达某一步之后,又回到了初始状态,那说明这种情况是没有结果的。


#include<iostream>
#include<stdio.h>
using namespace std;
int A,B,C;
void A_to_B(int &a,int &b,int &c)
{
        if(a>=B)
        {
                a=a-B;
                b=B;
        }
        else
        {
                b=a;
                a=0;
        }

        cout<<a<<' '<<b<<' '<<c<<endl;
}
void B_to_C(int &a,int &b,int &c)
{
        if(b>=C)
        {
                b=b-(C-c);
                c=C;
        }

        else
                {
                        c=b;
                        b=0;
                }
        cout<<a<<' '<<b<<' '<<c<<endl;
}

void C_to_A(int &a,int &b,int &c)
{
        a=a+c;
        c=0;
        cout<<a<<' '<<b<<' '<<c<<endl;
}


int main()
{
        int a,b,c,t;
        int s_a,s_b,s_c;
        scanf("%d,%d,%d,%d,%d,%d,%d",&A,&B,&C,&a,&b,&c,&t);
        s_a=a;
        s_b=b;
        s_c=c;
        while(a!=t&&b!=t&&c!=t)
        {
                if(b==0)
                        A_to_B(a,b,c);
                if(c==C)
                        C_to_A(a,b,c);
                else if(b!=0)
                        B_to_C(a,b,c);
                if(a==s_c&&b==s_b&&c==s_c)
                {
                        cout<<"不可能"<<endl;
                        break;
                }
        }
        return 0;
}




阅读更多
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/wr132/article/details/44411221
个人分类: 蓝桥杯
想对作者说点什么? 我来说一句

泊松分酒 c语言实现

2012年06月05日 4KB 下载

没有更多推荐了,返回首页

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭