解題思路:
首先我們肯定要用到約數之和定理
但是有個問題就是要怎麼用
根據經驗得知,約數最多也就六七個左右,不然直接就超了s的範圍。所以我們考慮用爆搜來做
但是用爆搜的話還是要優化一下思路和用什麼順序去搜尋。
順序:
按照p和α的順序來列舉可能要想一些剪枝:一旦s%這個當前的乘積==0(dfs的精髓)
那才能跳到下一層迴圈因為這樣才符合約數和定理
當s等於1+p的時候,直接就得到乙個答案。這樣就可以少遍歷幾個小於s的質數的個數有s除以logn個
時間複雜度:\(o(10\sqrt*100)\)
十個約數,然後再判斷質數的個數。k組資料
#include #include #include using namespace std;
const int n = 50000;
int primes[n], cnt;
bool st[n];
int ans[n], len;
void get_primes(int n)
}}bool is_prime(int x)
void dfs(int last, int prod, int s)
if (s - 1 > (last < 0 ? 1 : primes[last]) && is_prime(s - 1))
ans[len ++ ] = prod * (s - 1); // 不可以寫primes[last]因為可能是第乙個
for (int i = last + 1; primes[i] <= s / primes[i]; i ++ )
}int main()
}return 0;
}
解題技巧創造出來
演算法創造出來比較少
#include#include #include #include using namespace std;
const int maxn = 50000 + 10;
int ans[maxn], len, cnt;
int primes[maxn];
bool st[maxn];
void get_primes(int n)
}}bool is_prime(int n)
return true;
}void dfs(int last, int prod, int s)
if(is_prime(s - 1) && s - 1 > (last < 0 ? 1 : primes[last])) ans[len++] = prod * (s - 1); // primes[last + 1]的話可能會出錯
for(int i = last + 1; primes[i] <= s / primes[i]; i++)
} }int main()
}return 0;
}
acWing 1296 聰明的燕姿
用到了算數基本定理的思想,尤拉篩的不記錄最小質因子的板子,另外在優化dfs的時候還用到了小學生求素數的一點小思想,下面我們簡單說一下思路和分析幾個問題。思路 正約數之和等於s的數,容易想到直接列舉每乙個質數與每乙個質數的數量,然後進行優化。第乙個問題 尤拉篩存質數的陣列到底開多大?這個問題,誰一開始...
AcWing 1296 聰明的燕姿
原題鏈結 考察 dfs 約數 錯誤思路 倍數法求出所有約數,n要開到1e9必然mle且tle 正確思路 觀察約數之和的式子 s 1 p1 p1 2 p1 3 1 p2 p2 2 p2 3 要滿足能夠這種性質的數在1 2e9內較少.再繼續觀察,假設p全為2,1 2 1 2 22 1 2 22 23 當...
AcWing 1296 聰明的燕姿
算術基本定理 任何乙個大於1的自然數 n,如果n不為質數,那麼n可以唯一分解成有限個質數的乘積 則可以對s進行分解質因數 s p1 p2 pn 根據約數之和 sum 1 p1 1 p1 2 p1 1 pn 1 pn 而任何約數之和為s的數一定可以表示為約束之和公式的形式,即 s sum 因此除了1 ...