旧程序

public class JavaApplication7 {
    public static void main(String[] args) {
        String n = ""; // any given whole positive integer
        long solution = 0;
        double t = Double.parseDouble(n);
        double pow = nearpow(t);
        double nearpow = Math.pow(2, nearpow(t));
        double difference = Math.abs(t-nearpow);
        while(t!=1){
            if(t==nearpow){
                solution+=pow;
                t/=nearpow;
            }
            if(nearpow<t&&t!=1){
                t = t - difference;
                solution+=difference;
                t = t / nearpow;
                solution+=pow;
            }
            else if(nearpow>t&&t!=1){
                t+=difference;
                solution+=difference;
                t/=nearpow;
                solution+=pow;
                }
            }
        System.out.println(solution);
    }
    public static double nearpow(double t){
        double log = Math.log(t) / Math.log(2);

        long roundLog = Math.round(log);
        double dec = Math.abs(log-roundLog);
        long lowPow = (long)(log-dec);
        long highPow = lowPow+1;
        if(Math.abs(t-Math.pow(2,highPow))<Math.abs(t-Math.pow(2,lowPow))){
            return highPow;
        }
        else{
            return lowPow;
        }
    }
}


我正在编程以找到最小数量的运算,以使数字减至1,而有限的运算为+1 -1和/ 2,该测试适用于我用过的情况(4、5、15、30, 35、60个值,但是它无法对更高的值进行运算。任何人都可以看到更高的值的故障点,例如726给出了259个运算结果达到了1。

新程序

    String n = "54123";
    BigInteger t = new BigInteger(n);
    BigInteger one = new BigInteger("1");
    System.out.println(t);
    int solution =0;
    while(!t.equals(one)){
        if(((t.and(one)).equals(BigInteger.ZERO))){
            System.out.println(t+"/2 =");
            t=t.shiftRight(1);
            solution++;
            }
        else if((t.and(one)).equals(BigInteger.ONE)&&(((t.shiftRight(1).and(one))).equals(BigInteger.ONE))&&(((t.shiftRight(2).and(one))).equals(BigInteger.ONE))){
            System.out.println(t+"+2 =");
            t=t.add(one);
            solution++;

        }
        else if(t.and(one).shiftRight(1).equals(BigInteger.ZERO)&&t.and(one).equals(one)){
            System.out.println(t+"-1 =");
            t=t.subtract(one);
            solution++;
        }
    }
    System.out.print(solution);


我对按位运算还很陌生,所以我需要一点帮助来查找问题的新错误,因为我写的内容对我来说还是很新的,为增加按位运算的新用法,我必须在BigInteger中编写它,术语对我来说很难理解,但是使用我正在使用的术语应该可以,但是我找不到为什么不能使用的原因,以前使用的示例是762,它提供了259个操作,并且使用了新程序它给出了15,由于条款的新颖性,我仍然无法确定故障。
我写的解决方案(有效)

    String n = "762";
    BigInteger t = new BigInteger(n);
    BigInteger three = new BigInteger("3");
    BigInteger one = new BigInteger("1");
    System.out.println(t);
    int solution =0;
    while(!t.equals(one)){
        if(t.equals(three)){
            t=t.subtract(one);
            solution++;
        }
        if(((t.and(one)).equals(BigInteger.ZERO))){
            t=t.shiftRight(1);
            solution++;
            }
        else if((t.and(one)).equals(BigInteger.ONE)&&
(((t.shiftRight(1).and(one))).equals(BigInteger.ONE))){
            t=t.add(one);
            solution++;

        }
        else
if(t.and(one).shiftRight(1).equals(BigInteger.ZERO)&&t.and(one).equals(one)){
            t=t.subtract(one);
            solution++;
        }
    }
    System.out.print(solution);
}

}

最佳答案

正如2分法所暗示的,这是位操作的问题。

让我们看一下注释中提到的数字762(以10为底),又名1011111010(以2为底)(现已删除)。

除以2表示将位向右移动。除非数字被2整除,否则大概是不允许的,即最右边的位是0。

因此,如果我们可以右移,我们就可以做到。如果不是,我们可以减一以清除该位。

但是,如果下一位也为1,我们可以改为加1,因此在一个操作中多个1位被翻转为0,例如100111 + 1 = 101000

需要特别注意的是,11不应添加1,因为那样会进行11100101,即3个操作。相反,您减去1即可得到11101

          1011111010
 1:  /2 =  101111101
 2:  -1 =  101111100
 3:  /2 =   10111110
 4:  /2 =    1011111
 5:  +1 =    1100000
 6:  /2 =     110000
 7:  /2 =      11000
 8:  /2 =       1100
 9:  /2 =        110
10:  /2 =         11
11:  -1 =         10
12:  /2 =          1


在12个操作中找到解决方案。

现在,您只需为其编写代码。

10-07 22:42