題目大意:
給你十個數a1,a2,a10.範圍都是0到10000以內。n是這十個數相乘後的結果。求n的因子個數的個位數字。
解題思路:
這是很久以前抗電網賽的一道題目,其實也就是乙個數論題。
用到的知識就是算數基本定理推論:
任乙個大於1的整數a都能夠唯一的寫成
a=p1^a1*p2^a2……pk^ak > 0.
其中p1
然後a的因子個數就是(a1 + 1)*(a2 + 1)*(a3 + 1)……*(ak + 1)。
解決這個問題需要注意地的方有:
素數打表問題,因為每個數都是10000以內的數,所以需要知道100以內的素數都是什麼(至於為什麼10000這個數隻需要求出開方後的數字以內的素數,好像某個數學家證明過吧。。。。
1.我用的打表方法是先把is_prim[i]全部初始化為1.然後從2開始,如果這個數標記為1,則把它的所有倍數全部標記為0(成倍肯定不是素數)。
這樣外層迴圈100次,就可以求出100以內的素數,然後新開乙個陣列,將100以內的素數順序記錄下來,就可以處理10000以內的素數問題了。但是值得我們特別注意的是:這裡如果素數處理後結果不為1,說明它含有大於100的素數,我們不需要處理,它肯定是素數。
2.我用mapans來記錄素數出現的次數。之後迴圈一遍就可以求出結果。
**如下:
#include#include#include#include#include#includeusing namespace std; int num[10], pre[105]; mapans; //存素數個數 bool is_prim[105]; int k; void prim() //素數打表 for(int i = 2; i < 105; ++i) if(is_prim[i]) pre[k++] = i; //順序記錄素數 } int main() } if(sum != 1) //特別注意的地方!~ ans[sum]++; } map::iterator a; for(a = ans.begin(); a != ans.end(); ++a) //map的索引就是素數 result = (result * (a->second + 1)) % 10; printf("%d\n", result); } return 0; }
算數基本定理
算數基本定理 符號 a b a整除b a,b a,b最大公約數 a,b a,b最小公倍數 定理1 設p是素數,p a1a2,那麼p a1或p a2至少有乙個成立。一般的,若p a1 ak,則p a1,p ak至少有乙個成立。定理2 設a 1,那麼必有a p1p2 ps 其中pj 1 j s 是素數,...
素數問題 算數基本定理
定理 每個大於1 的正整數n都可以被唯一地寫成素數的乘積,在乘積中的素因子按照非降序排列。正整數n的分解式n p1 a1 p2 a2 pk ak 稱為n的標準分解式,其中p1,p2,pk是素數,p1 性質1 若n的標準素因子分解表示式為上面所述,設d n 為n的素因子的個數,則 d n a1 1 a...
尤拉定理及推論
有乙個 n 行 m 列的方陣。現在它要為這個方陣塗上黑白兩種顏色。規定左右相鄰兩格的顏色不能相同。請你幫它統計一下有多少種塗色的方法。由於答案很大,你需要將答案對1e9 7 取模。僅一行兩個正整數 n,m,表示方陣的大小。輸出乙個正整數,表示方案數對 1e9 7取模。2 241 n,m 10 100...