翻硬幣問題

2021-05-26 16:58:33 字數 4421 閱讀 7049

翻硬幣問題

翻硬幣問題有好幾種。

其中的一種是這樣的:

桌子上有q = m + n枚硬幣,m正面朝上,n枚反面朝上,每一輪翻p枚,在每一輪翻幣的時候,被翻的同一枚硬幣只能翻一次。問最少多少次能把所有的硬幣翻成全部正面或者反面朝上?根據問題的描述,問題實際上隱含:m 、n、 p > 0,m + n > p。

這個問題往往是計算機程式設計的問題。涉及廣度優先還是深度優先搜尋。

我對廣度優先還是深度優先搜尋了解的甚少。以下是用笨辦法求解的。

1)            幣面狀態數:用 (正面朝上幣數, 反面朝上幣數 )表示,顯然初始狀態是( m, n )。

假設第一輪翻幣翻反面(或者正面)的硬幣數為:i1<=n,則第一輪翻幣分別翻正面(或者反面)的硬幣數為:p - i1 ( m – ( p - i1 ) + i1, n - i1 + ( p - i1 ) ) = ( m – p + 2 * i1 ,  n + p - 2 * i1)

第二輪翻幣翻反面(或者正面)的硬幣數為:i2< n + p - 2 * i1,則第二輪翻幣分別翻正面(或者反面)的硬幣數為:p – i2 < m – p + 2 * i1, 此時幣面狀態數為:

( m – p + 2 * i1 – ( p – i2 ) + i2,  n + p - 2 * i1 + p - 2 * i2)

= ( m – 2 * p + 2 * ( i1 + i2 ) ,  n + 2 * p - 2 * ( i1 + i2 ) )

第三輪幣面狀態數:

( m – 3 * p + 2 * ( i1 + i2 + i3) ,  n + 3 * p - 2 * ( i1 + i2 + i3) )

……………………………………………………

第k輪幣面狀態數:

( m – k * p + 2 * ( i1 + i2 + … + ik) ,  n + k * p - 2 * ( i1 + i2 + … + ik) )

簡記:t = i1 + i2 + … + ik,則第k輪幣面狀態數可以標示為:

( m – k * p + 2 * t ,  n + k * p - 2 * t )

2)            完成翻幣條件

如果在某一輪翻幣後,正面幣數或者反面幣數能被p整除(其中之一等於零也被包含),則以後的每一輪全翻那個幣面數能被p整除的那一部分就可以完成翻幣,這一段話的意思就是:

m – k * p + 2 * t = s * p

或:n + k * p - 2 * t = s * p

稍微變換一下:

m – k * p + 2 * t = s * p —> ( s + k ) * p – 2 * t = m

或:n + k * p - 2 * t = s * p —> ( s – k ) * p + 2 * t = n

因此問題轉換為求解不定方程:

( s + k ) * p – 2 * t = m

或者( s – k ) * p + 2 * t = n

隱含條件:t >= 0, k >= 0, s >= 0, 如果t > 0, k > 0, s >= 0

m – k * p + 2 * t >= 0, n + k * p – 2 * t <= m + n —> k * p – 2 *t <= m

同時還必須:m – k * p + 2 * t <= m + n —> 2 * t – k * p <= n, n + k * p – 2 * t >= 0

3)            二元一次不定方程的整數解

二元一次方程的一般形式:

ax + by = c

其中a、b、c不為零,如果限定a、b、c是整數,而且限定求整數解,則關於二元一次方程有乙個定理:

定理1:設整係數二元一次不定方程:ax + by = c,假設d是a、b的最大公因數:d = ( a, b ),有解的條件是c能被d整除:(a, b )|c。

定理2:設整係數二元一次不定方程:ax + by = c,有一組整數解:x = x0, y = y0,則通解可以表示為:

x = x0 - b * t,y = y0 + a * t,t是整數。

二元一次方程的另一種形式:

a(x/c) + b(y/c) = 1

4)            回到翻幣問題

方法已經有了,讓我們回過頭來看看無解的情況,對於下面的整係數不定方程

( s + k ) * p – 2 * t = m: a = p, x = s + k, b = 2, y = -t

或者( s – k ) * p + 2 * t = n: a = p, x = s – k, b = 2, y = t

問題轉換為求

a * x + b * y = m或者a * x + b * y = n的整數解

定理1:如果m、n均為奇數,而p為偶數,無法完成翻幣。

例子1:

100枚正面朝上,1枚反面朝上,每次翻3,即 m = 100,n = 1,p = 3。

( s – k ) * p + 2 * t = n —> 3 * ( s – k ) + 2 * t = 1

可以觀察出:t = 2,s – k = -1是t最小的一組解,根據t = i1 + i2 + … + ik,因為

i1、i2、…、 ik >= 0,因為要求k最小,所以:t = i1 + i2 = 2,k = 2, s = 1, 根據本例,又有:i1<2,所以t = i1 + i2 = 2可能的解為:i1 = 0,1,i2 = 2、1這個給出翻幣的具體方案為:

1)第一輪全翻正面的硬幣,幣面狀態數:( 100 – 3 + 2 * 0 ,  1 +3 - 2 * 0 ) = ( 97, 4 ),第二輪把處於反面硬幣翻2枚過去,把處於正面的1枚翻過來,結果幣面狀態數

( 98, 3 ),第3輪全翻處於反面狀態的硬幣,結果幣面狀態數:( 101, 0 ),翻幣結果全翻成正面,翻幣完成。

2)第一輪翻2枚正面的硬幣過去,翻一枚反面的硬幣過來,幣面狀態數:( 100 – 3 + 2 * 1 ,  1 +3 - 2 * 1 ) = ( 99, 2 ),第二輪把處於反面硬幣翻1枚過去,把處於正面的2枚翻過來,結果幣面狀態數( 98, 3 ),第3輪全翻處於反面狀態的硬幣,結果幣面狀態數:( 101, 0 ),翻幣完成。這種方案,還有乙個解:99/3 + 1 = 34輪翻完,但不是最小解。

例子2100枚正面朝上,5枚反面朝上,每次翻7,即 m = 100,n = 5,p = 7。

考慮:( s – k ) * p + 2 * t = n —> 7 * ( s – k ) + 2 * t = 5,s - k = ( 5 - 2 * 6 ) / 7 = -1, t = 6,s = 1, k = 2, t = i1 + i2 = 1 + 5,(100, 5) --> ( 95, 10 ) --> ( 98, 7 ) --> ( 105, 0 ),3次翻完。

考慮:( s + k ) * p – 2 * t = m —> 7 * ( s + k ) – 2 * t = 100

s + k = ( 100 + 2 * t ) / 7 = ( 14 * 7 + 2 + 2 * t ) / 7 = 14 + 2 = 16次,t = 6,前面14次全翻正面的硬幣,結果變為:(100 – 14 * 7, 5 + 14 * 7 ) = ( 2, 103 ),然後把正面的一枚翻過去,反面的6枚翻過來,結果:( 7, 98 ),最後把正面的7枚全翻過去:( 0, 105 ),其他還有15種方案。

例子36枚正面朝上,5枚反面朝上,每次翻7,即 m = 6,n = 5,p = 7。

考慮:( s – k ) * p + 2 * t = n —> 7 * ( s – k ) + 2 * t = 5,s - k = ( 5 - 2 * 6 ) / 7 = -1, t = 6,s = 1, k = 2, t = i1 + i2 = 2+ 4;( 6, 5 ) --> ( 3, 8 ) --> ( 4, 7 ) --> ( 11, 0 ),3次翻完。

考慮:( s + k ) * p – 2 * t = m —> 7 * ( s + k ) – 2 * t = 6

s + k = ( 6 + 2 * t ) / 7 = ( 6 + 2 * t ) / 7 = 2次,t = 4,因為 t = 4 > 0, 所以k > 0,所以可能的解為: s = 0, k = 2,或者: s = 1, k = 1 。根據:

對於:s = 0, k = 2, t = i1 + i2 = 4, i1 = 1, 2, 3,i2 = 3, 2, 1相應的:p - i1 = 6, 5, 4, p – i2 = 4, 5, 6

i1 = 1:( 6, 5 ) —> ( 1, 10 ), m = 1 < 4 = p – i2無法進行下去。

i1 = 2:( 6, 5 ) —> ( 3, 8 ) —> i2 = 2 因為 m = 3 < 4 = p – i2無法進行下去。

i1 = 3:( 6, 5 ) —> ( 5, 6 ) —> i2 = 1因為 m = 5 < 6 = p – i2無法進行下去。

對於:s = 1, k = 1, t = i1 = 4:( 6, 5 ) —> ( 7, 4 ) —> ( 0, 11 )兩輪翻完。

翻硬幣(貪心)

歷屆試題 翻硬幣 時間限制 1.0s 記憶體限制 256.0mb 問題描述 小明正在玩乙個 翻硬幣 的遊戲。桌上放著排成一排的若干硬幣。我們用 表示正面,用 o 表示反面 是小寫字母,不是零 比如,可能情形是 oo oooo 如果同時翻轉左邊的兩個硬幣,則變為 oooo oooo 現在小明的問題是 ...

矇眼翻硬幣

有四個硬幣,正反面隨機地放在正方形的四個角,像這樣 正 反 正 反蒙著眼,每次可以同時翻兩個,請設計乙個策略,使得4個硬幣最後是同一面朝上。其實初始情況只有三種。正 反 反 正正 正 反 反正 正 正 反正 反 反 反 反 正 反 反2.1 正 正 正 反 反 反 正 反或者 2.2正 反 反 反 ...

翻硬幣 搜尋

有乙個n m的格仔,每個格仔上有乙個硬幣,用0表示正面朝上,1表示反面朝上。一次操作你可以將一行或一列的硬幣都反轉,問你是否能夠進行一系列的操作之後使得所有的硬幣都朝上。這道題和黑白棋那道類似,黑白棋那道有個啟發式資訊是乙個點不會反轉超過一次,這道題也是同樣的道理,一行或一列不會反轉超過一次。然後我...