前置技能:
1.反素數,推薦部落格:acdreamers講解反素數。
定義:對於任何正整數 n ,其約數的個數記做 f(n) .例如 f(1) = 1, f(6) = 4 .如果某個正整數n滿足:對於任意 i ( 0 < i < n ) ,都有 f( i ) < f( n ),則稱 n 為反素數.
反素數的應用:
(1). 給定乙個數 x,求乙個最小的正整數 n,使得 n 的約數個數為 x
(2). 求出 1~n 中約數個數最多的數
2.算數基本定理,又稱唯一分解定理。
內容:任何乙個大於1的自然數 n,都可以唯一分解成有限個質數的乘積n=p1^(a1)*p2^(a2)…pn^(an),這裡p1正因數個數為f(n)=(1+a1)(1+a2)…(1+an)。
其實網上的講解已經很多了,我主要是給每個題解都加了適當的注釋,希望剛開始學習反素數的朋友可能看懂。
思路:
以下問題的思路都是差不多的,所以先統一來說一下大體思路。根據算數基本定理我們可以知道,每個自然數都可以唯一寫為素數冪的乘積的形式。反之,我們可以通過素數冪的乘積得到每個自然數,我們可以通過深搜實現。當資料最大為 10^18 時,只需要前16個素數就夠了,得到的深搜樹最高的時候是60個2的乘積,樹高為60。
所以,我們可以通過深搜得到因子個數為 x 的最小數 n ,也可以通過深搜得到 1~n 中因子數最多數的最小數。
至於具體實現一兩句話也說不明白,還是看**和注釋吧。
題目1.codeforces number with the given amount of divisors
題意:給定乙個數 x,求乙個最小的正整數 n,使得 n 的約數個數為 x。
**:
#include#includetypedef long long ll;
ll ans;
int n,p[16]=;
void dfs(int pos,int num,ll tmp)
for(i=1;i<=63;i++) }
int main()
return 0;
}
題目2.bzoj 1053 反素數ant
題意:求出 1~n 中約數個數最多的最小數。
**:
#include#includetypedef long long ll;
ll ans;
int n,max,p[16]=;
void dfs(int pos,int num,ll tmp)
//如果當前值因子個數和最大因子數相等且當前值更小則更新
else if(num==max&&ans>tmp) ans=tmp;
for(i=1;i<=63;i++)
;void dfs(int pos,int limit,int num,ll tmp)
//如果當前值因子個數和最大因子數相等且當前值更小則更新
else if(num==max&&ans>tmp) ans=tmp;
//限制當前選擇素數的個數不能超過之前選擇的素數個數
for(i=1;i<=limit;i++)
{ //取i個第pos個素數
if(n/p[pos]
與Integer和int有關的乙個題目分析
題目來自牛客網 public class main 執行結果 true true false true i01 i02為true 當int和integer進行比較時,integer會自動拆箱為int,比較他們的值是否相等 i01 i03為true 因為當integer的值在 128 到 127這個範...
Java基礎程式設計練習 02 有關素數的判定與統計
第二個練習,看著簡單,但是自己寫出來漏洞百出,發現自己演算法部分真的太過欠缺,以後還得接著練。題目 判斷101 200之間有多少個素數,並輸出所有素數。程式分析 判斷素數的方法 用乙個數分別去除2到sqrt 這個數 如果能被整除,則表明此數不是素數,反之是素數。質數 prime number 又稱素...
三個和陣列有關的程式題目(C )
問題描述 有n個整數,使前面各數順序向後移動m個位置,最後m個數變成最前m個數 程式 includeusing namespace std int main cout cin m move a,n,m cout for i 0 i 執行介面 問題描述 先建立乙個陣列a 100 並置初始值為0,然乎輸...