常见逻辑问题java代码实现

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

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

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

实现代码:

[java]  view plain copy print ?
  1. public class PourOil {  
  2.     public static int[] a = { 1285 };//三个桶的容量  
  3.     public static int count=0;//记录到处方法的个数  
  4.     public static void main(String[] args) {  
  5.         int[][] f = new int[100][3];//记录三个桶内容量的变化  
  6.         f[0][0] = 12;//三个桶初始容量为 12 0 0   
  7.         f[0][1] = 0;  
  8.         f[0][2] = 0;  
  9.         DFS(f, 1);//通过深搜寻找下一桶内容量  
  10.     }  
  11.     //深搜  
  12.     private static void DFS(int[][] f, int x) {  
  13.         if (x > 100) {//控制最多倒油的次数  
  14.             return;  
  15.         }  
  16.         if (f[x - 1][0] == 6 || f[x - 1][1] == 6 || f[x - 1][2] == 6) {//只要三个桶中,任意一个桶容量出现6,表示达到目的,退出递归  
  17.             count++;  
  18.             System.out.print("方法"+count+":");  
  19.             print(f, x );//输出倒油的过程  
  20.             return;  
  21.         }  
  22.         for (int i = 0; i < 3; i++) {//三个桶之间互相倒油  
  23.             for (int j = 0; j < 3; j++) {  
  24.                 if (isTrue(f, x, i, j)) {//能倒油的条件  
  25.                     DFS(f,x+1);//倒油成功,寻找下一个倒油方法  
  26.                 }  
  27.             }  
  28.         }  
  29.     }  
  30.   
  31.     private static boolean isTrue(int[][] f, int x, int i, int j) {  
  32.         if (f[x - 1][i] == 0) {//要倒油的桶容量为0,则不能倒油  
  33.             return false;  
  34.         }  
  35.         if (f[x - 1][j] == a[j]) {//接收油的桶已满,则不能倒油  
  36.             return false;  
  37.         }  
  38.         if (i == j) {//自己不能与自己互相倒油  
  39.             return false;  
  40.         }  
  41.         pourOil(f, x, i, j);//倒油  
  42.         for (int t = 0; t < x; t++) {//判断在前面是否出现了这种状态,若出现,则不必再倒成这种状态,防止死循环(开始就遗漏了这个,进入死循环了呜呜呜呜)  
  43.             if (f[t][0] == f[x][0] && f[t][1] == f[x][1] && f[t][2] == f[x][2]) {  
  44.                 return false;  
  45.             }  
  46.         }  
  47.         return true;  
  48.     }  
  49.   
  50.     private static void pourOil(int[][] f, int x, int i, int j) {  
  51.         f[x][0] = f[x - 1][0];  
  52.         f[x][1] = f[x - 1][1];  
  53.         f[x][2] = f[x - 1][2];  
  54.         if (f[x - 1][i] > a[j] - f[x - 1][j]) {//倒油的桶中的容量,大于被倒桶中剩余的容量  
  55.             f[x][i] = f[x - 1][i] - (a[j] - f[x - 1][j]);  
  56.             f[x][j] = a[j];  
  57.         } else {//被倒的桶能装下倒油桶内的所有油  
  58.             f[x][j] += f[x][i];  
  59.             f[x][i] = 0;  
  60.         }  
  61.     }  
  62.   
  63.     private static void print(int[][] f, int x) {  
  64.         for (int i = 0; i < x-1; i++) {  
  65.             System.out.print(f[i][0] + "," + f[i][1] + "," + f[i][2] + " ---> ");  
  66.         }  
  67.         System.out.println(f[x-1][0] + "," + f[x-1][1] + "," + f[x-1][2]);  
  68.     }  
  69.   
  70. }  
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值