倒油问题

题目:有一位厨师要从盛12斤油(a桶)的桶中倒出6斤油来,可是手边只有盛8斤油(b桶)和盛5斤油(c桶)的两个桶,问如何操作才能将6斤取出来呢?

思路:思路其实很容易理解,就是三个桶之间互相倒油,直到倒出想要的结果,也就是其中任意一个桶中出现6即可。难就难在,如果直接让三个桶互相倒的话,很容易出现死循环,也就是a倒到b,下一步的时候,有让b倒回到a,所以要防止这种

情况的出现,才能找到结果。解决方法:先倒,然后看看三个桶中容量的状态,和前面的三个桶的状态是否有相同,若有,则不让这步进行,没有,则可以倒油。

实现代码:

public class PourOil {
	public static int[] a = { 12, 8, 5 };//三个桶的容量
	public static int count=0;//记录到处方法的个数
	public static void main(String[] args) {
		int[][] f = new int[100][3];//记录三个桶内容量的变化
		f[0][0] = 12;//三个桶初始容量为 12 0 0
		f[0][1] = 0;
		f[0][2] = 0;
		DFS(f, 1);//通过深搜寻找下一桶内容量
	}
	//深搜
	private static void DFS(int[][] f, int x) {
		if (x > 100) {//控制最多倒油的次数
			return;
		}
		if (f[x - 1][0] == 6 || f[x - 1][1] == 6 || f[x - 1][2] == 6) {//只要三个桶中,任意一个桶容量出现6,表示达到目的,退出递归
			count++;
			System.out.print("方法"+count+":");
			print(f, x );//输出倒油的过程
			return;
		}
		for (int i = 0; i < 3; i++) {//三个桶之间互相倒油
			for (int j = 0; j < 3; j++) {
				if (isTrue(f, x, i, j)) {//能倒油的条件
					DFS(f,x+1);//倒油成功,寻找下一个倒油方法
				}
			}
		}
	}

	private static boolean isTrue(int[][] f, int x, int i, int j) {
		if (f[x - 1][i] == 0) {//要倒油的桶容量为0,则不能倒油
			return false;
		}
		if (f[x - 1][j] == a[j]) {//接收油的桶已满,则不能倒油
			return false;
		}
		if (i == j) {//自己不能与自己互相倒油
			return false;
		}
		pourOil(f, x, i, j);//倒油
		for (int t = 0; t < x; t++) {//判断在前面是否出现了这种状态,若出现,则不必再倒成这种状态,防止死循环(开始就遗漏了这个,进入死循环了呜呜呜呜)
			if (f[t][0] == f[x][0] && f[t][1] == f[x][1] && f[t][2] == f[x][2]) {
				return false;
			}
		}
		return true;
	}

	private static void pourOil(int[][] f, int x, int i, int j) {
		f[x][0] = f[x - 1][0];
		f[x][1] = f[x - 1][1];
		f[x][2] = f[x - 1][2];
		if (f[x - 1][i] > a[j] - f[x - 1][j]) {//倒油的桶中的容量,大于被倒桶中剩余的容量
			f[x][i] = f[x - 1][i] - (a[j] - f[x - 1][j]);
			f[x][j] = a[j];
		} else {//被倒的桶能装下倒油桶内的所有油
			f[x][j] += f[x][i];
			f[x][i] = 0;
		}
	}

	private static void print(int[][] f, int x) {
		for (int i = 0; i < x-1; i++) {
			System.out.print(f[i][0] + "," + f[i][1] + "," + f[i][2] + " ---> ");
		}
		System.out.println(f[x-1][0] + "," + f[x-1][1] + "," + f[x-1][2]);
	}

}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-08-03 15:05:05

倒油问题的相关文章

倒油问题,广度优化搜索,java

有一位厨师要从盛12斤油(a桶)的桶中倒出6斤油来,可是手边只有盛8斤油(b桶)和盛5斤油(c桶)的两个桶,问如何操作才能将6斤取出来呢? class DumpOilBFS: import cn.hncu.sreach.putOil.common.Bucket; import cn.hncu.sreach.putOil.common.DumpCase; import cn.hncu.sreach.putOil.common.MySet; /* 有一位厨师要从盛12斤油(a桶)的桶中倒出6斤油来,

倒油瓶问题(平分水问题)(bfs)

#include<iostream> #include<stdio.h> #include<string.h> #include<queue> using namespace std; int vist[105][105][105],a,b,c; struct node {     int a,b,c;     int step; }s[105]; int sum=0; void bfs() {     queue<node>q;     mem

卖油翁

原文: 陈康肃公尧咨善射,当世无双 ,公亦以此自矜.尝射于家圃,有卖油翁释担而立,睨之,久而不去.见其发矢十中八九,但微颔之. 康肃问曰:“汝亦知射乎?吾射不亦精乎?”翁曰:“无他, 但手熟尔.”康肃忿然曰:“尔安敢轻吾射?”翁曰:“以我酌油知之.”乃取一葫芦置于地,以钱覆其口,徐以杓酌油沥之,自钱孔入,而钱不湿.因曰:“我亦无他, 惟手熟尔.”康肃笑而遣之. 此与庄生所谓解牛斫轮者何异?(为便于学生理解,此句在大多数教材中都没有出现,但在原文中的确提到,在此特补) *在部分语文课本中,“陈康肃

油瓶分油问题

油瓶分油问题举例描述: 例如:有三个大小不一样的且没有刻度的油瓶,其容量分别为12升.8升.5升:三个油瓶的初始油量为:12升.0升.0升:可以随意用某一瓶的油去灌满一瓶油,也可以把某一瓶的油全部倒入其他可以装下的一瓶油中,要求最后能得到一瓶装有6升的油. 编程要求: 用户分三行分别输入各个油瓶的容量和各个油瓶的初始油量,最后一行再输入要求得到的目标油量.要求程序能够判断能否得到目标油量,入能则输出每一次倒油的步骤,不能得到则输出"不能得到目标油量".只需要输出一中可行的分配方案即可.

IT痴汉的工作现状25-技术之养成

要想成为技术大牛,除了天赋以外,更与后天的刻苦努力分不开.伟仔我天生愚顿,工作多年后仍与大牛相差甚远,更加认为技术的养成是一个异常困难的过程. 是我不用功吗?我不这样认为.伟仔虽然是个懒人,但对于技术有着天生的热爱,这驱使我每天晚上仍会保持读书,写作,编码,看科技新闻.就像上一篇文章说的,"Just For Fun"让我保持对技术的持续动力. 是用功不够吗?嗯,程度的问题就见仁见智了.坦白讲,我每天的睡眠时间还是比较长的.我的意思是,在后半夜才休息的弟兄大有人在.用流行的话讲,那些更优

转: 罗辑思维:怎么样成为一个高手 文字版

感谢各位来到<罗辑思维>捧场 上一期节目我们隆重地给大家推荐了一个 付费的订阅产品 在我们罗辑思维开发的 得到APP里面 这个产品叫 精英日课 那主持它的是万维刚老师 因为我长期是他的读者和粉丝 所以我心知肚明 他出手开发的这个知识服务产品 品质有多高 所以我在美国专门跑了一趟 敦请他为我们的用户开发这个产品 所以上一期节目其实就是这个产品的广告 相信你也听出来了 特别不好意思 本期节目仍然是这个产品的广告 你看本期节目的题目 叫怎样才能成为一个高手 说实话 这期节目的策划案早就成型了 但是它

10道压得住场面的春节素菜,现在学也不晚!

天天大鱼大肉的熏陶下,素食反倒更加的抢手!!其实只要准备好食材,8~15分钟就能做出各种美味家常菜,有土豆.有茄子..各种公认食材最好找,操作时间最短的快手素菜,送给每一位童鞋!! 宫保豆腐 n食材:250g豆腐.100g红皮花生米.50g蒜苔.8粒紫天椒.20g芝麻.1勺糖.1勺香醋.2大勺生油.1/2勺老抽.1勺料酒.1勺盐.1勺淀粉.1勺鸡精 做法:1)豆腐切成丁备用.2)调料汁调好,蒜苔.紫天椒切粒备好.3)芝麻炒香,花生米用油炸熟,各装入碟备用.4)炒锅下油烧热,下豆腐丁炸至金黄沥油捞

14.设计模式_模板方法模式

一.引言 提到模板,大家肯定不免想到生活中的"简历模板"."论文模板"."Word中模版文件"等,在现实生活中,模板的概念就是--有一个规定的格式,然后每个人都可以根据自己的需求或情况去更新它,例如简历模板,下载下来的简历模板的格式都是相同的,然而我们下载下来简历模板之后我们可以根据自己的情况填充不同的内容要完成属于自己的简历.在设计模式中,模板方法模式中模板和生活中模板概念非常类似,下面让我们就详细介绍模板方法的定义,大家可以根据生活中模板的概

菜谱大全

上万种菜色供您选择 文章来源:http://www.haoservice.com/docs/30 支持格式: JSON/XML 请求方式: GET/POST 明文方式请求参数:   名称 类型 必填 说明   key string 是 API KEY   menu String 是 查询的菜谱名   pn Int 是 页码   rn Int 是 每页条数 密文方式请求参数:   名称 类型 必填 说明   IsEncrypt bool 是 是否密文传输方式   key string 是 API