筆試面試題 —— 天平稱重與二進位制
阿新 • • 發佈:2019-01-22
有人曾問帳前卒一道題:至少需要多少個砝碼,才能稱出1~50g物體?
這道題有兩個變種:
1.至少需要多少砝碼(左物右碼),才能稱出1~50g物體?
2.至少需要多少砝碼(砝碼可以放在任意一邊),才能稱出1~50g物體?
第一問可以變為: 至少多少個數字相加,可以表示1~50之間的任意數。又可以演變為:如何快速的從一堆蘋果中取出你想要的個數?
第一問對於每個數字其實就是兩種狀態,加、不加。也就是1,0. 對應的公式就是,對於任意數x
x = 1*a0 + 2*a1 + 4*a2...+2^k*ak (a0...ak 可取0或者1)
也就是計算機界常見的2進製表示法。當全部ai都取1時,那麼1+2+4...+2^k = 2^(k+1) - 1 >= x, 將x=50帶入,k+1即為所求。所以第一問的答案就是 log(50+1) 取上整
帳前 卒這樣解決了第一問,那麼第二問應該就是第一問的變種。
因為砝碼可以放左邊、右邊、不放。那麼就有三種狀態(-1,1,0). 這就是如何用三種狀態來標示一個數。那麼
x = 1*a0 + 3*a1 + 9*a2 + ... + 3^k*ak 其中ai可以取-1,0,1
當全部ai都取1時,那麼1+3+9...+3^k = (3^(k+1) - 1)/2 >=x, 把x=50帶入,那麼k+1即為所求
所以第二問的答案是 log3(x*2+1) 取上整 為 5
帳 前 卒又想起快速冪級運算
a^k 如果一次乘個a,那麼需要乘k次。如果使用二分法 那麼 只需要乘log(k)取上整次就可以做完。
a^0 | a^1 | a^2 | a^3 | a^4 | a^5 |
1 | a^1 | a^2 | a1*a^2 | 1*a^4 | a^1 * a^4 |
這樣表示就會發現其實a^k 其實就是把k表示為2進位制的形式。
5 就是 101 就是 a^1 * a^4
下面寫就比較好寫程式了。
total=1; // total就是所求,k就是冪,a就是底數
while(k) {
if (k&1) total*=a;
a*=a;
k>>=1;
}