1. 程式人生 > >筆試面試題 —— 天平稱重與二進位制

筆試面試題 —— 天平稱重與二進位制

有人曾問帳前卒一道題:至少需要多少個砝碼,才能稱出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^0a^1a^2a^3a^4a^5
1a^1a^2a1*a^21*a^4a^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;
}