取石子遊戲

2021-07-04 14:40:11 字數 1618 閱讀 9609

有兩堆石子,數量任意,可以不同。遊戲開始由兩個人輪流取石子。遊戲規定,每次有兩種不同的取法,一是可以在任意的一堆中取走任意多的石子;二是可以在兩堆中同時取走相同數量的石子。最後把石子全部取完者為勝者。

現在給出初始的兩堆石子的數目a和b,如果輪到你先取,假設雙方都採取最好的策略,問最後你是勝者還是敗者。如果你是勝者,輸出win,否則輸出lose。

例如,a=3,b=1, 則輸出win(你先在a中取乙個,此時a=2,b=1,此時無論對方怎麼取,你都能將所有石子都拿走)。

首先,我從0開始列舉所有可能的情況,發現:

其中,所有loose的情況為(2,1),(5,3),(7,4),(6,10)...,用圖形表示為:

因為:2 - 1 = 1

5 - 3 = 2

7 - 4 = 3

10 - 6 = 4

於是猜測所有lose的情況為a - b = k(設a > b),k從1一直遞增,a,b取值不重複,從1開始。

**思路是,構造乙個包含所有lose情況的陣列p,陣列中所有lose的數對值相同。比如,(i,j)為乙個lose對,那麼p[i]等於p[j],這樣給定a,b時,判斷p[a]和p[b]是否相等,如果相等,那麼其lose。 

from __future__ import print_function

def get_failed_pairs(a, b):

c = a if a > b else b

pairs = [0] * (c+1)

k = 1

for i in range(1, c + 1):

if i + k <= c and not pairs[i]:

pairs[i] = pairs[i+k] = i

k += 1

return pairs

def take_the_stone(a, b, pairs):

if a != b and (pairs[a] == pairs[b] != 0):

return false

return true

pairs = get_failed_pairs(a, b)

print(take_the_stone(a, b, pairs) and 'win' or 'lose')

雖然**通過了,然而它並不完美的,使用了陣列,在a或b值很大時,會造成時間和空間上的損耗,解決辦法是,不使用陣列,利用這個規律進行遞推,看能否找到lose的數值對。

另,在結題報告中看到一種規律叫做『奇異態勢』,有兩個特點:

1. 無法從乙個奇異態勢一步走到另乙個奇異態勢;

2. 任何非奇異態勢可以一步走到某乙個奇異態勢。

可構建以下奇異態勢,前幾組分別為(0,0),(1,2),(3,5),(4,7),(6,10),(8,13)....滿足:

1)各奇異態勢間無重複元素;

2)步長(|a-b|)遞增,保證各不相同

取石子遊戲

如下 include include intmain k b a temp floor k 1.0 sqrt 5 2.0 if temp a printf 0 n else printf 1 n return 0 一 巴什博奕 bash game 只有一堆n個物品,兩個人輪流從這堆物品中取物,規定每...

取石子遊戲

有兩堆石子,數量任意,可以不同。遊戲開始由兩個人輪流取石子。遊戲規定,每次有兩種不同的取法,一是可以在任意的一堆中取走任意多的石子 二是可以在兩堆中同時取走相同數量的石子。最後把石子全部取完者為勝者。現在給出初始的兩堆石子的數目,如果輪到你先取,假設雙方都採取最好的策略,問最後你是勝者還是敗者。in...

取石子遊戲

取石子遊戲 time limit 1000ms memory limit 10000k total submissions 25176 accepted 7961 description 有兩堆石子,數量任意,可以不同。遊戲開始由兩個人輪流取石子。遊戲規定,每次有兩種不同的取法,一是可以在任意的一堆...