最近幾次 AC 中,用建表的為 (39ms, 280KB),不建表的為 (79ms, 148KB),
「看起來」是建表比不建表用了大略兩倍的空間,來節省一半的時間,但並不代表哪種比較好。
接下來分別說明自己建表和不建表的方法
大致就是遵循質數的判定規則,對某數 N
,依序拿整數 2 ~ sqrt(N)
來除 N
,能整除表示合數,都不整除則為質數。
稍微做了最佳化,將質數用 6
歸納,除了 2, 3, 5
之外,(6k), (6k+2), (6k+4)
必能被 2 整除,而 (6k+3)
必能被 3 整除,所以其他質數必定能寫成 (6n+1)
或 (6n+5)
(但 (6n+1), (6n+5) 的數不一定就是質數,如 25=6x4+1=5x5)
用上述規則,再判斷 N
是否為質數時,只要找 2, 3, 5, 7(=6x1+1), 11(=6x1+5), ...
來判斷即可
由於題目給最大正整數為 100000000
,代表只要找到 1~10000
之間的質數即可
先用上述「不建表」的邏輯,對 1~10000
的數判定是否為質數,並存到一個陣列裡,這邊我是使用 std::vector
,表建好之好,再就題目給的數,從剛剛建好的表中,找出質數來判定即可
稍微做了最佳化,1~10000
的數判斷完,開了另一個陣列 isPrime[10001]
,儲存該數是為質數,之後只要遇到 1~10000
的數,只要查 isPrime[N]
就好,不用再做是否整除的判斷
若還有做得不夠好,就是我要繼續學的部分了
最近幾次 AC 中,用建表的為 (39ms, 280KB),不建表的為 (79ms, 148KB),
「看起來」是建表比不建表用了大略兩倍的空間,來節省一半的時間,但並不代表哪種比較好。接下來分別說明自己建表和不建表的方法
先講「不建表」
大致就是遵循質數的判定規則,對某數
N
,依序拿整數2 ~ sqrt(N)
來除N
,能整除表示合數,都不整除則為質數。稍微做了最佳化,將質數用
6
歸納,除了2, 3, 5
之外,(6k), (6k+2), (6k+4)
必能被 2 整除,而(6k+3)
必能被 3 整除,所以其他質數必定能寫成(6n+1)
或(6n+5)
(但 (6n+1), (6n+5) 的數不一定就是質數,如 25=6x4+1=5x5)用上述規則,再判斷
N
是否為質數時,只要找2, 3, 5, 7(=6x1+1), 11(=6x1+5), ...
來判斷即可
再講「建表」
由於題目給最大正整數為
100000000
,代表只要找到1~10000
之間的質數即可先用上述「不建表」的邏輯,對
1~10000
的數判定是否為質數,並存到一個陣列裡,這邊我是使用std::vector
,表建好之好,再就題目給的數,從剛剛建好的表中,找出質數來判定即可稍微做了最佳化,
1~10000
的數判斷完,開了另一個陣列isPrime[10001]
,儲存該數是為質數,之後只要遇到1~10000
的數,只要查isPrime[N]
就好,不用再做是否整除的判斷
若還有做得不夠好,就是我要繼續學的部分了
照你的不建表寫一直TLE(9),可以幫我看看嗎
先不談建表或不建表。
你的 def p(number):
就有很大的改善空間
for i in range(2,ab)
連偶數都試除了, 能快嗎。
當然這樣也是過不了啦。
想想別的方法,
先不談建表或不建表。你的 def p(number):就有很大的改善空間for i in range(2,ab)連偶數都試除了, 能快嗎。當然這樣也是過不了啦。想想別的方法,
跩三小
我上面的回應, 算客氣吧。
cpp 的 user
即使寫法普通,勉強也能 ac
python 就是比較慢,
硬要參考 cpp 的解法,往往就是超時。
非得要絞盡腦汁才能通過,
這也是樂趣之一。
上面我只是想請他趕快想其他的方法,
上面的方法,無法 AC