旧程序
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
,因为那样会进行11
→100
→10
→1
,即3个操作。相反,您减去1
即可得到11
→10
→1
。
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个操作中找到解决方案。
现在,您只需为其编写代码。