深搜解决倒油问题 --面向过程

/**
 * 从盛12斤油(a桶)的桶中倒出6斤油来,可是手边只有盛8斤油(b桶)
 * 和盛5斤油(c桶)的两个桶,问如何操作才能将6斤取出来呢?
 * 面向过程方法倒油:
 */
public class PoulOil2 {
	public static int max[] = new int[] { 12, 8, 5 };// 桶的最大容量
	public static final int MAXTIMES = 25;// 最多倒几次
	public static int ways = 0;// 有几种方式

	public static void main(String[] args) {
		// 初始化--行是过程,列是3个桶的当前油量
		int[][] kegs = new int[MAXTIMES][3];
		kegs[0][0] = 12;
		kegs[0][1] = 0;
		kegs[0][2] = 0;

		// 深搜
		// 目标油量,二维数组,当前次数
		dfs(6, kegs, 1);
	}

	/**
	 * 深搜 
	 * cur-1:前一个状态,已经倒好了 
	 * cur :当前的状态,准备要倒的 
	 * cur+1:下一个状态
	 */
	public static void dfs(int aim, int[][] kegs, int cur) {
		// 是否得到答案
		if (kegs[cur - 1][0] == aim || kegs[cur - 1][1] == aim || kegs[cur - 1][2] == aim) {
			System.out.print("方法" + (++ways) + ":(" + cur + ")");
			print(kegs, cur - 1);
			return;
		}
		// i->j倒油
		for (int i = 0; i < 3; i++) {
			for (int j = 0; j < 3; j++) {
				if (canPoul(i, j, kegs, cur)) {// 能倒就倒
					// 倒油
					// poulOil(i,j,kegs,cur);//canPoul()已經倒了一次
					// 深搜
					dfs(aim, kegs, cur + 1);
				}
			}
		}
	}

	/**
	 * 当前情况能否倒到cur位置 
	 * i->j
	 */
	public static boolean canPoul(int i, int j, int[][] ks, int cur) {
		// 1.i==j不能倒
		// 2.i==0不能倒
		// 3.j==max[j]不能倒
		if (i == j || ks[cur - 1][i] == 0 || ks[cur - 1][j] == max[j]) {
			return false;
		}
		// 4.不能倒成跟原来的一样,否则就屎循环了
		poulOil(i, j, ks, cur);
		for (int k = 0; k < cur; k++) {
			// 如果有一个组跟原来的一样就 return false
			if (ks[k][0] == ks[cur][0] && ks[k][1] == ks[cur][1] && ks[k][2] == ks[cur][2]) {
				return false;
			}
		}
		// System.out.println(MAXTIMES);
		return true;
	}

	/**
	 * 倒油i->j
	 */
	public static void poulOil(int i, int j, int[][] ks, int cur) {
		//并不知道i,j是什么,但是剩下的一个没参与倒的桶也必须延续上一轮的油
		ks[cur][0] = ks[cur - 1][0];
		ks[cur][1] = ks[cur - 1][1];
		ks[cur][2] = ks[cur - 1][2];
		if (ks[cur - 1][i] > max[j] - ks[cur - 1][j]) {// 只能将i倒进一部分到j
			ks[cur][i] = ks[cur - 1][i] - (max[j] - ks[cur - 1][j]);
			ks[cur][j] = max[j];
		} else {// 能将i全部倒进j
			ks[cur][j] = ks[cur - 1][i]+ks[cur - 1][j];
			ks[cur][i] = 0;
		}

	}

	/**
	 * 打印过程
	 */
	public static void print(int[][] ks, int cur) {
		System.out.print(ks[0][0] + "、" + ks[0][1] + "、" + ks[0][2]);
		for (int i = 1; i <= cur; i++) {
			System.out.print(" -> " + ks[i][0] + "、" + ks[i][1] + "、" + ks[i][2]);
		}
		System.out.println();
	}
	/*
	if(ks[cur-1][i]<=max[j]-ks[cur-1][j]){
		ks[cur][i] = 0;
		ks[cur][j] = ks[cur-1][j]+ks[cur-1][i];  
	}else {//只能将i倒进一部分到j
		ks[cur][i] = ks[cur-1][i]-(max[j]-ks[cur-1][j]);  
		ks[cur][j] = max[j]; 
	}*/
}

你可能感兴趣的:(数据结构与算法,java修炼笔记,Java-我的大学生涯)