認識反素數

定義:對於任何正整數x,其約數的個數記做g(x)。例如g(1)=1,g(6)=4.如果某個正整數x滿足:對於任意i(0<i<x) , 都有g(i)<g(x),則稱x爲反素數。
性質:
(1)一個反素數的所有質因子必然是從2開始的連續若干個質數,因爲反素數是保證約數個數爲的這個數儘量小
(2)同樣的道理,如果:p=2^t1*3^t2* 5^t3*7^t4…..,那麼必有t1>=t2>=t3>=….

引題:給定一個數n,求一個最小的正整數x,使得的約數個數爲n。

那麼我們所要求的就是g(x) = n,且在0到x之間都有g(i)<g(x),這樣x纔可以保證最小。之後就是如何去求一個數的約數個數啦,如下圖
下面關於12的約數的圖
因此可以知道從根節點帶葉子節點的總的路徑數就是12的總約數個數。那麼我們再求一個數的約數個數時的根本就是計算這個樹的路徑總數,用搜索來解決,代碼如下

void dfs(int i, int lim, ll base, int num) //其中i爲搜索到第幾層,也就是在搜索prime[i]這個素數。lim是當前這個素數指數的最大值。base是當前值。num是當前值base的約數個數。
{
    if(num > n) return ;  //當約數個數大於所求n時,返回空
    if(num == n && ans > base) ans = base; 
    for(int j = 1; j <= lim; j++) //依據是性質2
    {
        if(ans/prime[i] < base || num*(j+1) > n) return ; //若base*prime[i]大於ans時就不用繼續dfs下去,因爲要保證ans爲最小值。或當約數個數大於所求約數個數n是也停止搜索。
        base *= prime[i]; //循環一次要乘一次,不是隻有dfs時再乘
        if(n%(num*(j+1)) == 0)
            dfs(i+1, j, base, num*(j+1));
    }
}
dfs(0, 62, 1, 1)  //一個數unsigned long long類型的2最多爲62次

相關題:
http://codeforces.com/problemset/problem/27/E
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1562
http://acm.timus.ru/problem.aspx?space=1&num=1748
http://acm.hdu.edu.cn/showproblem.php?pid=4542

發佈了45 篇原創文章 · 獲贊 21 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章