最大运行时间:1s
最大运行内存: 512M
题目描述:
你有一架天平。现在你要设计一套砝码,使得利用这些砝码可以称出任意 小于等于 N 的正整数重量。
那么这套砝码最少需要包含多少个砝码?
注意砝码可以放在天平两边。
输入格式
输入包含一个正整数 N。
输出格式
输出一个整数代表答案。
样例输入
7
样例输出
3
样例说明
3 个砝码重量是 1、4、6,可以称出 1 至 7的所有重量。
1 = 1;
2 = 6 − 4(天平一边放 6,另一边放 4);
3 = 4 − 1;
4 = 4;
5 = 6 − 1;
6 = 6;
7 = 1 + 6;
少于 3 个砝码不可能称出 1 至 7 的所有重量。
评测用例规模与约定
对于所有评测用例,1 ≤ N ≤ 1000000000。
给定一个正整数N求出,最少需要多少个砝码能称出1~N之间所有重量
emmmmmmm
我们看啊
如果我们只在一边放砝码 那么当前这个砝码就只有 放与不放 两种选择
那么 砝码 放与不放两种情况 往数学上想 是不是 很像二进制中的 1 和 0 两个数呢?
我们看 k 位的二进制数呢?最大为
2
k
−
1
2^{k} - 1
2k−1, 最小为 1
k 位的二进制数的范围为
[
1
,
2
k
−
1
]
[1, 2^{k} - 1]
[1,2k−1]
那么规定 0是不放, 1是放
也就能称出 1 ~ 2 k − 1 2^{k}-1 2k−1 之间所有数了
比如要凑一个 8
那么我们要凑出 1 ~ 8 之间所有数
8 的二进制为 1000
所以 就需要
2
3
、
2
2
、
2
1
、
2
0
2^{3}、2^{2}、2^{1}、2^{0}
23、22、21、20 这几个砝码 (注:只能放天平的一边哦)
那么 需要称出 1 ~ 8 之间所有数的话
就需要知道 8 是几位二进制数即可
为了方便 也为了好看一点
需要凑的数 | 砝码 | 二进制 |
---|---|---|
1 | 2 0 2^{0} 20 | 0001 |
2 | 2 1 2^{1} 21 | 0010 |
3 | 2 0 + 2 1 2^{0} + 2^{1} 20+21 | 0011 |
4 | 2 2 2^{2} 22 | 0100 |
5 | 2 2 + 2 0 2^{2} + 2^{0} 22+20 | 0101 |
6 | 2 2 + 2 1 2^{2} + 2^{1} 22+21 | 0110 |
7 | 2 2 + 2 1 + 2 0 2^{2} + 2^{1} + 2^{0} 22+21+20 | 0111 |
8 | 2 3 2^{3} 23 | 1000 |
那么看看 本题这个天平 两边都可以放砝码
砝码 可以放左边 也可以放右边 也可以不放
这么说 那么按上面有个的想法 往三进制看看
可是 0 1 2 分别表示什么呢
拿 2 来看
2 的 三进制为 2
可是 单单只是一个2的话 也就只是一个砝码
他能称出2的重量 但无法称出1的重量
而 如果像上面一样用3的倍数来称出2话是
3
1
−
3
0
3^{1} - 3^{0}
31−30 这样的
需要两个砝码
很显然 三进制不行 那么 用什么能代替 三进制 来接这题呢
这里就需要用到一个和三进制很像的一个进制 — 平衡三进制
三进制 的数码为 0, 1, 2
平衡三进制 的数码为 -1, 0, 1
且 十进制转平衡三进制 也是不同于 普通三进制哦
-1无论在哪里写都不是很清楚 那么接下来所有 -1 都用 Z 来先代替
数 | 普通三进制 | 平衡三进制 |
---|---|---|
1 | 1 | 1 |
2 | 2 | 1Z |
3 | 10 | 10 |
4 | 11 | 11 |
5 | 12 | 1ZZ |
6 | 20 | 1Z0 |
7 | 21 | 1Z1 |
8 | 22 | 10Z |
9 | 100 | 100 |
10 | 101 | 101 |
… | … | … |
那么再用平衡三进制 替换 普通三进制看看
那么规定 Z是放左边, 0是不放, 1是放右边
2 的 平衡三进制为 1Z
很显然
3
1
3^{1}
31 放右边,
3
0
3^{0}
30 放左边 这样就成称出 2了
那么看再 5
5 的 平衡三进制为 1ZZ
3
2
3^{2}
32 放右边,
3
1
3^{1}
31和
3
0
3^{0}
30 放左边 这样就成称出 5了
那么 实践一下 也是称出个 8
8的平衡二进制为 10Z
所以需要用到
3
2
、
3
1
、
3
0
3^{2}、3^{1}、3^{0}
32、31、30 这几个砝码
需要凑的数 | 砝码 | 平衡三进制 |
---|---|---|
1 | 3 0 3^{0} 30 | 001 |
2 | 3 1 − 3 0 3^{1} - 3^{0} 31−30 | 01Z |
3 | 3 1 3^{1} 31 | 010 |
4 | 3 1 + 3 0 3^{1} + 3^{0} 31+30 | 011 |
5 | 3 2 − 3 1 − 3 0 3^{2} - 3^{1} - 3^{0} 32−31−30 | 1ZZ |
6 | 3 2 − 3 1 3^{2} - 3^{1} 32−31 | 1Z0 |
7 | 3 2 − 3 1 − + 3 0 3^{2} - 3^{1} -+3^{0} 32−31−+30 | 1Z1 |
8 | 3 2 − 3 0 3^{2} - 3^{0} 32−30 | 10Z |
然后就上面一样 如果要称出 1 ~ n 之间 所有的数的话
只需要算出 n 的平衡三进制有多少位即可
如果是 普通的进制的话
那么可以直接调用toString()函数 然后算出他有多少位即可
但是平衡三进制的话 就不行了
看上面的平衡三进制 与 三进制的表 就能看出
比如5的 平衡三进制 与 三进制的位数 就不同
所以我们这里需要从 1 开始看 他需要多少个 3次幂 才能大于 n
综上所述
我们这题 只需要算出 n 的平衡三进制有多少位即可
也就是 ∑ i = 1 ∞ 3 i > = n \sum_{i = 1}^{\infty} 3^{i} >= n ∑i=1∞3i>=n 求出满足条件的第一个 i 即可
import java.io.*;
import java.util.*;
public class Main
{
public static void main(String[] args)
{
int n = sc.nextInt();
int ans = 0, mul = 1;
int cnt = 0;
while (ans < n)
{
cnt++;
ans += mul;
mul *= 3;
}
out.println(cnt);
out.flush();
out.close();
}
static Scanner sc = new Scanner(System.in);
static PrintWriter out = new PrintWriter(System.out);
}
如果有说错的 或者 不懂的 尽管提 嘻嘻
一起进步!!!