zoukankan      html  css  js  c++  java
  • 【NOIP普及组】【DFS】2016年模拟考试(9.3)——母亲的牛奶

    五、母亲的牛奶(cow.cpp

    【题目描述】

    农民约翰有三个容量分别是ABC升的桶,ABC分别是三个从120的整数。

    最初,AB桶都是空的,而C桶是装满牛奶的。

    有时,约翰把牛奶从一个桶倒到另一个桶中,直到被灌桶装满或原桶空了。由于节约,牛奶不会有丢失。

    写一个程序去帮助约翰找出当A桶是空的时候,C桶中牛奶所剩量的所有可能性。

    【输入】

    1行:3个整数ABC

    【输出】

    1行:升序地列出当A桶是空的时候,C桶牛奶所剩量的所有可能性。

    【样例输入】

    2 5 10

    【样例输出】

    5 6 7 8 9 10

    ----------------------------------------------------------------------------------------------------

    这道题……应该,可能,也许,是广搜简单一点。

    但是,我用的深搜……花了四五十分钟……

    真的不会广搜,找时间补补。

     

    大体思路:

    就递归,定义vis数组(三维)判重,if(!vis)return; 然后只要此处容量没有满,就将其他两个(也要满足不为空)往这里面倒。总共3个大if,6个小if,还有n个问号表达式(事实上老师不推荐用,容易出问题,换成if也无妨,但有一点点复杂)。

     

    代码如下:

    #include<cstdio> 5 
    int a,b,c;
    int vis[22][22][22];
    void milk(int x,int y,int z)//xyz分别是abc桶剩余的数量
    {
    	if(vis[x][y][z])//判重
    		return;
    	vis[x][y][z]=1;//发现一种就记录一种
    	if(x<a)//判断当前桶是否已满
    	{
    		if(y)//其他两个桶只要不为空就能往里倒
    			milk(a>x+y?x+y:a,a>x+y?0:y-(a-x),z);//这里到下面去解释
    		if(z)
    			milk(a>x+z?x+z:a,y,a>x+z?0:z-(a-x));
    	}
    	if(y<b)//以此类推
    	{
    		if(x)
    			milk(b>x+y?0:x-(b-y),b>x+y?x+y:b,z);
    		if(z)
    			milk(x,b>y+z?y+z:b,b>y+z?0:z-(b-y));
    	}
    	if(z<c)
    	{
    		if(x)
    			milk(c>x+z?0:x-(c-z),y,c>x+z?x+z:c);
    		if(y)
    			milk(x,c>y+z?0:y-(c-z),c>y+z?y+z:c);
    	}
    }
    int main()
    {
    	freopen("cow.in","r",stdin);
    	freopen("cow.out","w",stdout);//文件输入输出
    	scanf("%d%d%d",&a,&b,&c);
    	milk(0,0,c);
    	for(int i=b;i>=0;i--)
    		for(int j=0;j<=20;j++)//数据中最大c为20,且需从小到大(升序)输出,所以从0到20查
    			if(vis[0][i][j])
    				printf("%d ",j);//没有处理最后的空格
    	return 0;
    }

    关于问号表达式应该都知道,然后我拿出一个来解释那个递归:

    milk(a>x+y?x+y:a,a>x+y?0:y-(a-x),z);

    首先第一个参数:

    a>x+y?x+y:a,因为此处是将y(b)桶倒至x(a)桶,所以这里是处理x桶。当将y桶全部倒入x桶都没有达到最大容量(a>x+y)时,就将y全部倒入,返回x+y;反之则是x桶满了,也就是a,所以返回a。

    第二个参数:

    a>x+y?0:y-(a-x),同上,这里是处理y桶。同上,全部y桶倒入后自然是返回0;反之,也就是y桶没倒完,x桶满了,y桶就只减去x桶还差多少倒满的值(a-x)就行了,返回y-(a-x)。

    不关第三个参数的事,所以不变。

                                                                                                                                                                           By WZY

  • 相关阅读:
    Android 查看通讯录Contacts是否发生变化
    卓尼斯ZT-180评測
    C++中的单例模式
    Android 动画之ScaleAnimation应用具体解释
    java的静态代理
    词性标注
    ubuntu 11.04安装笔记
    机房收费系统学生下机结账小结
    MyBatis入门学习(一)
    !!!!OpenWrt系列教程汇总
  • 原文地址:https://www.cnblogs.com/LinqiongTaoist/p/7203771.html
Copyright © 2011-2022 走看看