演算法很美之數學問題

2021-09-11 07:10:12 字數 2693 閱讀 2109

描述

今天我們要認識一對新朋友,alice與bob。

alice與bob總是在進行各種各樣的比試,今天他們在玩乙個取石子的遊戲。

在這個遊戲中,alice和bob放置了n堆不同的石子,編號1…n,第i堆中有a[i]個石子。

每一次行動,alice和bob可以選擇從一堆石子中取出任意數量的石子。至少取1顆,至多取出這一堆剩下的所有石子。

alice和bob輪流行動,取走最後乙個石子的人獲得勝利。

假設每一輪遊戲都是alice先行動,請你判斷在給定的情況下,如果雙方都足夠聰明,誰會獲得勝利?

對於這個遊戲有乙個非常神奇的結論:

對於乙個局面,當且僅當a[1] xor a[2] xor ... xor a[n] = 0時,該局面為p局面。

輸入

第1行:1個整數n。表示石子堆數。1≤n≤100

第2行:n個整數,第i個整數表示第i堆石子的個數a[i],1≤a[i]≤10000

輸出第1行:1個字串,若alice能夠獲勝輸出"alice",否則輸出"bob"

樣例輸入

3

3 2 1

樣例輸出

bob
#include

main()

if(fl==0)

printf

("bob");

else

printf

("alice");

return0;

}

描述

小ho:小hi,上次我學會了如何檢測乙個數是否是質數。於是我又有了乙個新的問題,我如何去快速得求解[1,n]這個區間內素數的個數呢?

小hi:你自己有什麼想法麼?

小ho:有!我一開始的想法是,自然我們已經知道了如何快速判定乙個數是否是質數,那麼我就直接將[1,n]之間每乙個數判定一次,就可以得到結果。但我發現這個方法太笨了。

小hi:確實呢,雖然我們已經通過快速素數檢測將每一次判定的時間複雜度降低,但是n個數字的話,總的時間複雜度依舊很高。

小ho:是的,所以後來我改變了我的演算法。我發現如果乙個數p是質數的話,那麼它的倍數一定都是質數。所以我建立了乙個布林型別的陣列isprime,初始化都為true。我從2開始列舉,當我找到乙個isprime[p]仍然為true時,可以確定p一定是乙個質數。接著我再將n以內所有p的倍數全部設定為isprime[p*i]=false。

寫成偽**為:

isprime = true

primecount = 0

for i = 2 … n

if isprime[i] then

primecount = primecount + 1

multiple = 2

while (i * multiple ≤ n)

isprime[i * multiple] = false

multiple = multiple + 1

end while

end if

end for

小hi:小ho你用的這個演算法叫做eratosthenes篩法,是一種非常古老的質數篩選演算法。其時間複雜度為o(n log log n)。但是這個演算法有乙個冗餘的地方:比如合數10,在列舉2的時候我們判定了一次,在列舉5的時候我們又判定了一次。因此使得其時間複雜度比o(n)要高。

小ho:那有沒有什麼辦法可以避免啊?

小hi:當然有了,乙個改進的方法叫做eular篩法,其時間複雜度是o(n)的。

第1行:1個正整數n,表示數字的個數,2≤n≤1,000,000。

輸出第1行:1個整數,表示從1到n中質數的個數

樣例輸入

9
樣例輸出

4
eular質數篩法的偽**:

isprime = true

primelist =

primecount = 0

for i = 2 .. n

if isprime[i] then

primecount = primecount + 1

primelist[ primecount ] = i

end if

for j = 1 .. primecount

if (i * primelist[j] > n) then

break

end if

isprime[ i * primelist[j] ] = false

if (i % primelist[j] == 0) then

break

end if

end if

end for

附本人ac**

#include

#include

char isprime[

1000001];

int primelist[

78498];

int main()

for(j =

1; j <= primecount && i*primelist[j]

<=

n; j++)}

}printf

("%d\n"

, primecount)

;return0;

}

演算法筆記 數學問題

原題鏈結 原理 最大公約數 遞迴 歐幾里得演算法 最小公倍數 得到a,b的最大公約數d 最小公倍數 a d b include include intgcb int a,int b 求最大公約數 intmain printf d n d return0 include include include...

2018 6 18 數學問題

define crt secure no deprecate 求正整數n的質因數的個數。120 2 2 2 3 5 所以最後輸出時5 10 9 n至多只存在乙個大於sqrt n 的素因數 這裡只需要篩選到100000就可以 通過素數表,不斷試除,最後求出各個冪指數的和 include 素數表找到10...

2018 6 18 數學問題

2 4 3 8 2 3 3 對分母n 和分子 a進行因子分解後,找到其對應的冪指數相除結果最小的即為最後結果 對n!分解素因數 計算n 中將有幾個p因子ans 計算n p,有n p個整數可以向n 提供乙個p因子 ans n p 計算n p p 有n p p 個整數可以向n 提供兩個因子,相較於上乙個...