1. 程式人生 > >P1463 [SDOI2005]反素數ant

P1463 [SDOI2005]反素數ant

ref blog inline 多少 最大的 type 整數 fin ttr

P1463 [SDOI2005]反素數ant

題目描述

對於任何正整數x,其約數的個數記作g(x)。例如g(1)=1、g(6)=4。

如果某個正整數x滿足:g(x)>g(i) 0<i<x,則稱x為反質數。例如,整數1,2,4,6等都是反質數。

現在給定一個數N,你能求出不超過N的最大的反質數麽?

輸入輸出格式

輸入格式:

一個數N(1<=N<=2,000,000,000)。

輸出格式:

不超過N的最大的反質數。

輸入輸出樣例

輸入樣例#1:
1000
輸出樣例#1:
840


一道水題 就是找最大的反素數


我們先建一棵搜索樹
以12為例 技術分享

技術分享
從根節點到每個葉子節點路徑上的數乘起來就是12的約數
我們可以按照這個思路來找反素數 具體解釋見代碼

這個題n<=2*10^9 不會超過int
log2(2*10^9)大約在30左右
所以我們每一個素數最多遞歸30層
記錄當前到了第幾個素數 這個素數用了幾遍 產生幾個約數 當前的now是多少

 1 #pragma GCC optimize(2)
 2 #include <cstdio>
 3 #include <cctype>
 4 
 5 typedef long long LL;
 6 
 7 LL ans;
 8 
 9 #define Inline __attri10
bute__( ( optimize( "-O2" ) ) ) 11 12 int n,Now; 13 14 int prime[20]={0,2,3,5,7,11,13,17,19,23,29}; 15 16 Inline void DFS(int num,int Np,LL now) { 17 if(now>n) return;//如果當前數now大於n 就返回 最優性剪枝 18 if(Np>Now||Np==Now&&now<ans) {Now=Np;ans=now;} 19 // 如果當前約數個數大於目前全局最優解 或者約數個數等於全局最優解但是當前數要大於目前全局最優解 就更新
20 LL t=1,s=0;// s為當前素數使用了幾次 t則就是當前素數使用了s次產生的約數 21 for(int i=1;i<=30;++i) { 22 t*=prime[num]; 23 ++s; 24 if(now*t>n) return;// 當前數now乘約數t產生的數大於n 說明當前搜索方向無法產生解 25 DFS(num+1,Np*(s+1),now*t); 26 } 27 } 28 29 int hh() { 30 scanf("%d",&n); 31 DFS(1,1,1); 32 printf("%lld\n",ans); 33 } 34 35 int sb=hh(); 36 int main(int argc,char**argv) {;}

 

P1463 [SDOI2005]反素數ant