c語言稱重砝碼
這個問題確實又是一個三進位制的問題。記得以前我探討過一個稱壞乒乓球的問題,和這個問題有異曲同工之處。
這個問題其實包含三個子問題:
1.稱量需要多少個砝碼。
2.每個砝碼的質量是多少。
3.稱量某一重物,達到平衡狀態時,每個砝碼如何擺放。
先討論第1個問題。
不管是天平還是普通桿秤,砝碼的放置位置都有三個,一是不放在秤上,二是放在秤上與被稱物不在一起,三是放在秤上與被稱物在一起。樓主的“標準答案”並沒有考慮第三種情況。
我們還是以天平作為衡器來描述問題吧。
我們可以設被稱量物總是放在左邊的,這樣天平的左右盤的意義就不同了。
每個砝碼在稱量中可以有三種狀態。放在左邊、不放上天平、放在右邊。
那麼N個砝碼最多可以組合出3^N種狀態。這3^N種狀態除了全不放上天平外其它狀態都有一個對稱的狀態。
假設有某一狀態是左邊放了Sa砝碼,右邊放了Sb砝碼(Sa,Sb都是砝碼集S的子集,並且Sa、Sb不相交),那麼必然會有另一狀態(左邊放Sb右邊放Sa)與之對應。
設左邊砝碼總重量為Wa,右邊為Wb,則這一平衡狀態下的被稱物重量為Wb - Wa。
與它對稱的狀態在平衡時被稱物重量為Wa - Wb。
很顯然,這一對狀態下被稱物重量必然有一個為負值。負重量在現實中不存在。
所以N個砝碼能表示的正狀態為(3^N - 1)/2種。也就是能表示的最大的被稱物質量。
由此,稱量重量為W的重物時需要的砝碼數是 N = log3(2 * W + 1)。這是小曹說錯的地方。
接下來討論第2個問題。
有了上面的討論其實這第2個問題的結論已經出來了。狀態呈現三進位制計數的性質,所以每個砝碼3的冪次,這樣即可保證狀態無重疊且連續。
從小到大,第i個砝碼的質量應該是 3^(i - 1)。
最後討論第3個問題。
將狀態表示成三進位制數,每一位對應一個砝碼(質量為該位的基)的取值為0、1、2。現在我們建立三進位制數與被稱量物重量的對應關係。
我們規定0表示該位對應砝碼放在左邊,1表示不放在天平上,2表示放在右邊。
這麼規定是有意義的。
我們希望用三進位制數的變化情況與被稱物質量的變化對應。也就是說被稱物質量越大這個三進位制數的值也越大。
在這種規定下三進位制0的意義是什麼?
是所有砝碼都放在左邊,即與被稱量物放在一起。這時如果要天平平衡,那被稱量物具有的將是負質量。
而天平上什麼都不放的狀態(零質量)對應的數值是...1111111。即每位都是1。
所以這裡只是應用了部分的三進位制計數性質,而非正常意義下的三進位制數。
這裡的0表示的其實是負無窮,而無限多的1表示的是十進位制數0。它其實是將整個整數域對映到了非負整數域。
而我們使用的是有限位三進位制數,且最高位為2(略去更高位的無限個1)。
這個概念比較抽象,如果理解不了可以跳過。
由於每位為1表示零質量,而我們用N個砝碼。所以我們計算的基準值應為(N^3 - 1) / 2。
對於重量為W的重物,它對應的三進位制數值為。
(3^N - 1) / 2 + W
這個三進位制值的每一位的值將表示該位對應砝碼的放置位置。
這個問題其實包含三個子問題:
1.稱量需要多少個砝碼。
2.每個砝碼的質量是多少。
3.稱量某一重物,達到平衡狀態時,每個砝碼如何擺放。
先討論第1個問題。
不管是天平還是普通桿秤,砝碼的放置位置都有三個,一是不放在秤上,二是放在秤上與被稱物不在一起,三是放在秤上與被稱物在一起。樓主的“標準答案”並沒有考慮第三種情況。
我們還是以天平作為衡器來描述問題吧。
我們可以設被稱量物總是放在左邊的,這樣天平的左右盤的意義就不同了。
每個砝碼在稱量中可以有三種狀態。放在左邊、不放上天平、放在右邊。
那麼N個砝碼最多可以組合出3^N種狀態。這3^N種狀態除了全不放上天平外其它狀態都有一個對稱的狀態。
假設有某一狀態是左邊放了Sa砝碼,右邊放了Sb砝碼(Sa,Sb都是砝碼集S的子集,並且Sa、Sb不相交),那麼必然會有另一狀態(左邊放Sb右邊放Sa)與之對應。
設左邊砝碼總重量為Wa,右邊為Wb,則這一平衡狀態下的被稱物重量為Wb - Wa。
與它對稱的狀態在平衡時被稱物重量為Wa - Wb。
很顯然,這一對狀態下被稱物重量必然有一個為負值。負重量在現實中不存在。
所以N個砝碼能表示的正狀態為(3^N - 1)/2種。也就是能表示的最大的被稱物質量。
由此,稱量重量為W的重物時需要的砝碼數是 N = log3(2 * W + 1)。這是小曹說錯的地方。
接下來討論第2個問題。
有了上面的討論其實這第2個問題的結論已經出來了。狀態呈現三進位制計數的性質,所以每個砝碼3的冪次,這樣即可保證狀態無重疊且連續。
從小到大,第i個砝碼的質量應該是 3^(i - 1)。
最後討論第3個問題。
將狀態表示成三進位制數,每一位對應一個砝碼(質量為該位的基)的取值為0、1、2。現在我們建立三進位制數與被稱量物重量的對應關係。
我們規定0表示該位對應砝碼放在左邊,1表示不放在天平上,2表示放在右邊。
這麼規定是有意義的。
我們希望用三進位制數的變化情況與被稱物質量的變化對應。也就是說被稱物質量越大這個三進位制數的值也越大。
在這種規定下三進位制0的意義是什麼?
是所有砝碼都放在左邊,即與被稱量物放在一起。這時如果要天平平衡,那被稱量物具有的將是負質量。
而天平上什麼都不放的狀態(零質量)對應的數值是...1111111。即每位都是1。
所以這裡只是應用了部分的三進位制計數性質,而非正常意義下的三進位制數。
這裡的0表示的其實是負無窮,而無限多的1表示的是十進位制數0。它其實是將整個整數域對映到了非負整數域。
而我們使用的是有限位三進位制數,且最高位為2(略去更高位的無限個1)。
這個概念比較抽象,如果理解不了可以跳過。
由於每位為1表示零質量,而我們用N個砝碼。所以我們計算的基準值應為(N^3 - 1) / 2。
對於重量為W的重物,它對應的三進位制數值為。
(3^N - 1) / 2 + W
這個三進位制值的每一位的值將表示該位對應砝碼的放置位置。
#include<stdio.h>
#include<math.h>
int f(int w)
{
return ceil(log(w * 2 + 1) / log(3));
}
void print_weight(int w)
{
int n, a;
const char * B[] = {"L", "O", "R"};
n = f(w);
for(a = (int)(pow(3, n) - 1) / 2 + w; a; a /= 3)
printf("%5s ", B[a % 3]);
}
int main()
{
int w, n, i, t;
printf("Input weight : ");
scanf("%d", &w);
n = f(w);
printf("It needs %d weights.\n", n);
printf("Every weights is:\n");
for(i = 0, t = 1; i < n; i++, t *= 3) printf("%5d ", t);
puts("");
print_weight(w);
return 0;
}
#include<math.h>
int f(int w)
{
return ceil(log(w * 2 + 1) / log(3));
}
void print_weight(int w)
{
int n, a;
const char * B[] = {"L", "O", "R"};
n = f(w);
for(a = (int)(pow(3, n) - 1) / 2 + w; a; a /= 3)
printf("%5s ", B[a % 3]);
}
int main()
{
int w, n, i, t;
printf("Input weight : ");
scanf("%d", &w);
n = f(w);
printf("It needs %d weights.\n", n);
printf("Every weights is:\n");
for(i = 0, t = 1; i < n; i++, t *= 3) printf("%5d ", t);
puts("");
print_weight(w);
return 0;
}
假如現在只有一個1g的砝碼,那麼我們只能稱1g的重量,我們把能稱的重量集合記為S, 現在的S1 = {1}。
現在給了我另外一個砝碼m(m!=1)克。那我們能稱的重量為1, m-1, m , m+1, 若m-1!=1,那麼我們就能稱4個重量,S2 = {1, m-1, m, m+1},比如說給的m=3,那麼我們能稱的重量為S2 = {1,2,3,4},很顯然,在某個時刻,只能取S中的一個值,若取了1和3相當於取4。即S2 = {S1, m-S1, m, m+S1}.
現在我們有了1g,3g的砝碼,那麼再給我一個砝碼m,我能稱的重量最多能有多少個呢?肯定是1,2,3,4,m-4,m-3,m-2,m-1,m,m+1,m+2,m+3,m+4,若m=9,則連續稱的重量為S3= {1,2,3,4,5,6,7,8,9,10,11,12,13}。即S3 = {S2,m-S2, m, m+S2}。
不難看出,這裡有個規律: 假設手頭上有m個砝碼,可以稱的連續重量為n個,那麼再給一個砝碼,此砝碼重量為2n+1,那麼能稱的連續重量為3n+1個,即已經能稱的1到n的重量,加上新加的砝碼2n+1依次減去1到n的重量得到的n+1到2n的n個重量,再加上新加的砝碼本身的重量2n+1,再加上2n+1依次加上1到n的重量得到的2n+2到3n+1的n個重量。此時砝碼個數為m+1。
m個砝碼能稱的最多重量為(3^m-1)/2。第m個砝碼的重量為3^(m-1)。
文章出處:http://bbs.bccn.net/thread-372721-1-1.html
相關文章
- C 語言程式碼總結
- C語言程式設計規範——名稱縮寫C語言程式設計
- C語言貪吃蛇原始碼C語言原始碼
- C語言簡單程式碼程式C語言
- C++ 的指令碼語言:ChaiScriptC++指令碼AI
- 重學C語言_資料結構與基礎語法C語言資料結構
- C語言C語言
- 聊聊C語言/C++—程式和程式語言C語言C++
- C語言字串C語言字串
- C語言(一)C語言
- C語言: returnC語言
- C語言 typedefC語言
- C語言與嵌入式C語言的區別C語言
- C語言學習方法,怎麼學習C語言?C語言
- 嵌入式c語言編碼規範C語言
- C語言學生管理系統原始碼C語言原始碼
- C語言建立空白Windows視窗程式碼C語言Windows
- go語言與c語言的相互呼叫GoC語言
- C語言記憶體洩露很嚴重,如何應對?C語言記憶體洩露
- 1901:The C programming language !(C語言)C語言
- C語言教程——03 C語言結構C語言
- C語言:extern用法C語言
- C語言版本迭代C語言
- C語言 截圖C語言
- C語言 - 字串拼接C語言字串
- C語言加強C語言
- c語言複習C語言
- c語言入門C語言
- C語言位操作C語言
- 初識C語言C語言
- c語言筆記C語言筆記
- C語言基礎C語言
- c語言作業C語言
- C語言 共用體C語言
- C語言 備份C語言
- C語言指標C語言指標
- Linux-C語言LinuxC語言
- c語言_遞迴C語言遞迴
- C語言陣列C語言陣列