Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/340.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 最快的硬币运动_Java_Puzzle - Fatal编程技术网

Java 最快的硬币运动

Java 最快的硬币运动,java,puzzle,Java,Puzzle,我有一个难题,我需要通过在某些条件下删除17个,将一个数字减为零。下面是让你理解的谜题 从138枚硬币开始,找到最少的移动次数,精确到0枚硬币。每次移动你可以(a)弃掉17枚硬币,(b)弃掉1枚硬币或(c)弃掉一半硬币(但前提是你目前拥有偶数枚硬币)。编写一个程序,测试所有可能的移动组合,并打印最快移动组合所需的移动数 我用下面的代码找到了最快的移动。现在,我需要找出其他可能的动作,但我被卡住了。有人能帮忙吗 package com.infy.cis.test; public class Co

我有一个难题,我需要通过在某些条件下删除17个,将一个数字减为零。下面是让你理解的谜题

从138枚硬币开始,找到最少的移动次数,精确到0枚硬币。每次移动你可以(a)弃掉17枚硬币,(b)弃掉1枚硬币或(c)弃掉一半硬币(但前提是你目前拥有偶数枚硬币)。编写一个程序,测试所有可能的移动组合,并打印最快移动组合所需的移动数

我用下面的代码找到了最快的移动。现在,我需要找出其他可能的动作,但我被卡住了。有人能帮忙吗

package com.infy.cis.test;

public class CoinMovementPuzzle {

    static int times=0;

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        numDiv(138,2,17,1);

    }
    public static void numDiv(int a, int b,int c,int d) {

        if(a!=0)
        {
            int remainder=a%b;;
            if(remainder==0 && a>=2)
            {
                evenNumber(a,b);
            }
            else if(remainder!=0 && a>=17)
            {
                oddNumber17(a,c);
            }
            else
            {
                oddNumber1(a,d);
            }

        }
        System.out.println("FINAL"+times);
        }
    private static void oddNumber1(int a,int d) {
        // TODO Auto-generated method stub
        a=a-d;
        times=times+1;
        System.out.println("odd number::"+a+"::"+times);
        numDiv(a, 2,17,1);

    }
    private static void oddNumber17(int a,int c) {
        // TODO Auto-generated method stub
        //int rem;
        int rem=a%c;
        a/=c;
        times=times+a;

        System.out.println("odd number::"+a+"::"+times);
        numDiv(rem, 2,17,1);

    }
    private static void evenNumber(int a,int b) {
        // TODO Auto-generated method stub
        a/=2;
        times=times+1;
        //System.out.println(a/=b);
        //remainder=a%b;
        System.out.println("Value of a"+a);
        System.out.println("even number::"+a+"::"+times);
        numDiv(a, 2,17,1);


    }
}

此解决方案将按相反顺序打印出最佳(但不是全部)移动: 它的工作原理是使用广度优先搜索算法,尝试所有可能的组合,并在每个阶段选择最佳组合

import java.util.ArrayList;
import java.util.List;

public class Main {


    List<String> getMinMoves(int amount){

        if (amount <= 0){
            return new ArrayList<String>();
        }

        int numMovesSubtractingSeventeen = Integer.MAX_VALUE;
        List<String> movesSubtractingSeventeen = null;
        if (amount >= 17){
            movesSubtractingSeventeen = getMinMoves(amount - 17);
            numMovesSubtractingSeventeen = 1 + movesSubtractingSeventeen.size();
        }

        List<String> movesSubtractingOne = getMinMoves(amount - 1);
        int numMovesSubtractingOne = 1 + movesSubtractingOne.size();

        List<String> movesDividingByTwo = null;
        int numMovesDivideByTwo = Integer.MAX_VALUE;
        if (amount % 2 == 0) {
            movesDividingByTwo = getMinMoves(amount/2);
            numMovesDivideByTwo = 1 + movesDividingByTwo.size();
        }

        if (numMovesSubtractingSeventeen < numMovesSubtractingOne){
            if (numMovesSubtractingSeventeen < numMovesDivideByTwo){
                movesSubtractingSeventeen.add("Subtract 17 from " + amount);
                return movesSubtractingSeventeen;

            } else {
                movesDividingByTwo.add("Divide " + amount + " by 2");
                return movesDividingByTwo;
            }
        } else {
            if (numMovesSubtractingOne < numMovesDivideByTwo) {
                movesSubtractingOne.add("Subtract 1 from " + amount);
                return movesSubtractingOne;
            }
            else {
                movesDividingByTwo.add("Divide " + amount + " by 2");
                return movesDividingByTwo;
            }
        }
    }



    public static void main(String[] args) {
        Main main = new Main();
        List<String> moves = main.getMinMoves(138);
        System.out.println("Min number of moves: " + moves.size());
        for (String move : moves){
            System.out.println(move);
        }
    }

}
import java.util.ArrayList;
导入java.util.List;
公共班机{
列表getMinMoves(整数金额){
如果(金额=17){
movessubtractingseven=getMinMoves(金额-17);
nummovesSubscriptingsEventeen=1+MovesSubtracting 17.size();
}
List movessubtratingone=getMinMoves(金额-1);
int nummovessublatingone=1+movessubtratingone.size();
List movesDividingByTwo=null;
int numMovesDivideByTwo=整数.MAX_值;
如果(金额%2==0){
movesDividingByTwo=getMinMoves(金额/2);
nummovesdividbytwo=1+movesDividingByTwo.size();
}
if(nummovessublatingeventien

如果有多个解决方案是最优的,您可以修改代码以返回一组列表。

这类似于更改问题。如果您想找到移动次数最少的方法,那么动态规划方法就可以了。您可以设置一个数组
a[i]
i=0..138
,并从最小到最大进行构建。从
a[0]=0开始。存储在
a[i]
中的数字是
min(a[i-1]+1,a[i-17]+1,a[i/2]+1(如果我是偶数))
。努力达到
a[138]
。然后要找到实际的移动顺序,找出
a[138-1]
a[138-17]
a[138/2]
中哪一个小于
a[138]
,然后重复,直到你点击
0

a[0] = 0
for i = 1 to 138
  if (i<17) 
    if (i odd)
      a[i] = a[i-1]+1
    else // i even
      a[i] = min(a[i-1]+1, a[i/2]+1)
   else // i >= 17
     if (i odd)
       a[i] = min(a[i-1]+1, a[i-17]+1)
     else // i even
       a[i] = min(a[i-1]+1, a[i-17]+1, a[i/2]+1)
   // end if
// a[138] now contains the minimum number of moves 
// find the actual sequence by working backwards
i = 138
while (i>0)
  if a[i-1] < a[i]
    print -1
    i = i-1
  else if a[i-17] < a[i]
    print -17
    i = i-17
  else if a[i/2] < a[i]
    print /2
    i = i/2
  else 
    // shouldn't end up here
    print error
您的初始呼叫应该是
sequenceOfMoves(“,138)


要回答这个问题,您需要存储序列而不是打印序列,然后在递归完成后,在存储中搜索最短的移动序列。打印所有内容,将最短者标记为优胜者。

首先格式化代码,然后请告诉我们您的具体位置和尝试。我认为您需要的是。创建一棵树,其中第一步是一半、17和1。这将创建3个节点。对于每个节点,使用合法移动创建新节点。当您创建了所有节点(换句话说,当您的所有子节点都为零)后,您就创建了包含所有移动组合的树。您确定您的算法找到了最快的移动吗?我看到,运行代码可以得到6个移动的结果,这是最快的路径。但是接下来的一系列动作。从138开始,除以2(69),减去1(68),除以2(34),除以2或减去17(17),减去17(0)。只有5步。我投票结束这个问题作为离题,因为这是关于解决一个数学问题,而不是编程。嗨,爱德华,能不能请你对数组部分进行重新校准。我想不起来。也许一小段代码会有所帮助。谢谢..我画了算法。谢谢爱德华:)。这帮了大忙!
sequenceOfMoves(string sequenceSoFar, int targetNumber)
  if targetNumber is 0, print sequenceSoFar // done
  if targetNumber > 0 sequenceOfMoves(sequenceSoFar + "-1", targetNumber-1)
  if targetNumber > 16 sequenceOfMoves(sequenceSoFar + "-17", targetNumber-17)
  if targetNumber is even sequenceOfMoves(sequenceSoFar + "/2", targetNumber/2)