【题目描述】
处女座热爱做物理实验,为了实验,处女座必须要精确的知道物品的质量。处女座准备自己设计一套砝码,每一个砝码都是正整数,这套砝码必须能够精确测量出n以内所有正整数的质量,处女座想要知道至少需要多少个砝码。你可以在天平的任意一边放置砝码。
【输入描述】
一行,一个正整数n
1<=n<=10^1000
【输出描述】
一个整数,表示最少的砝码数。
【样例】
示例1
输入
20
输出
4
说明
你可以选择1,2,6,11
1=1
2=2
3=1+2
4=6-2
5=6-1
6=6
7=6+1
8=6+2
9=6+2+1
10=11-1
11=11
12=11+1
13=11+2
14=11+2+1
15=11+6-2
16=11+6-1
17=11+6
18=11+6+1
19=11+6+2
20=11+6+2+1
思路:
对于每个砝码,其可以选择放左边、不放、放右边,所以可按照三进制进行排列,即使用 n+1 个砝码,有:
,对于每个 n ,可以称出的范围在
因此,假设有 k 个砝码,可以称出不大于 的所有组合
那么对于加入的第 k+1 个砝码 ,有:
即 恰好为
的中值,离两个端点的距离均为
,这个值正好是 k 个砝码可以覆盖的范围
由于给出的 n 明显超出 long long 的范围,因此需使用大数来结合公式做,,容易解出 k 最大约等于 3000,利用枚举或二分均可以很快的解出 n 的值
【源代码】
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner input=new Scanner(System.in);
String str=input.nextLine();
BigInteger n = new BigInteger(str);
n=n.multiply(new BigInteger("2"));
n=n.add(n.ONE);
int left=1,right=3000;
BigInteger three=new BigInteger("3");
int res=0;
while(left<=right) {
int mid=(left+right)/2;
if(three.pow(mid).compareTo(n)<0) {
left=mid+1;
}
else {
right=mid-1;
res=mid;
}
}
System.out.println(res);
}
}