问题描述:
你有一架天平。现在你要设计一套砝码,使得利用这些砝码可以称出任意 小于等于 N 的正整数重量。
那么这套砝码最少需要包含多少个砝码?
注意砝码可以放在天平两边。
输入格式:
输入包含一个正整数 N。
输出格式:
输出一个整数代表答案。
样例输入:
7
样例输出:
3
样例说明:
3 个砝码重量是1 、 4 、 6 可以称出 1 至 7 的所有重量。
1 = 1;
2 = 6 − 4 (天平一边放 6 6,另一边放 4 4);3 = 4 − 1 ;
4 = 4;
5 = 6 − 1 ;
6 = 6 ;
7 = 1+ 6 ;
评测用例规模与约定
对于所有评测用例,1≤N≤1000000000。
感受:
这个题我做的太SB
了,最开始我用二进制表示的,提交对了一个,然后经过我的认真思考我发现了样例给出的 1,4,6 是坑,这个只能表示 1 ~ 7,我自己找到的是 1, 2, 6因为我可以表示1 ~ 9我还窃喜了好一会,然后我兴致勃勃用自己找到的这个规律去推导,大概花了半小时,写了两篇草稿,然后自信得提交, 这次我想应该可以对很多。gusses what?
没错,没错,还是只对了一个!!!!
当时我看着测试的结果,直呼热烈的马😭。
失败原因:
总结失败原因:不够贪心。
解题思路:
首先结果是最少砝码
但为什么说失败的原因是不够贪心?
贪心体现在:
同样都是增加一个砝码,为什么我们不选择一个能让我们称重范围尽可能大的砝码?
首先,如果要称重重量为1的话,只能选择质量为1的砝码。
然后为了扩充测量范围,我们需要增加,砝码,在这里我们就需要贪心一点。
选1,2可以满足 1 = 1,2 = 2,3 = 1 + 2 ,4 = ?
选1,3可以满足 1 = 1,2 = 3 - 1,3 = 3,4 = 3 + 1,5 = ?
选择1,4可以满足 1 = 1,2 = ?
选择1,5可以满足 1 = 1,2 = ?
… … … … … …
由上我们可以看出在只能选择两个砝码的情况下1,3是最好的可以表示的范围为1 ~ 4。
如果我们要扩充第三个砝码:
我们已经清楚前两个砝码可以测量的最大值是4,如果要再添一个砝码,我们为什么不让添加后的砝码能够测量的范围尽可能大?
为了满足我们的贪心,我们遵循添加的砝码尽可能大的原则,由于下一个需要满足的重量是5,所以新添加砝码的最大质量是 weight - 4 = 5,得到 weight = 9,
进一步推算可以发现前两个砝码能拼出 1 ~ 4,用9减去它们就是5 ~ 8,加上它们就是10 ~ 13
再加上9本身,刚好三个砝码的测量范围就是1 ~ 13
同理下一个扩充的砝码就是27
下下一个 81
… … …
… … …
如果推导到这一步,就不难发现,添加砝码的规律就是三进制。
代码:
import java.util.Scanner;
public class Main {
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int sum = 1;//测量范围
int j = 1;//需要砝码数
while(sum < n) {
j ++;//添加砝码
sum = sum + (int)Math.pow(3, j - 1);//新的测量范围
}
System.out.print(j);
}
}
这道题虽然代码少,但是真是难想。😭