洛谷 P1463、POI2002、HAOI2007 反素數
阿新 • • 發佈:2019-01-20
最大 ext 離開 out nbsp 搜索剪枝 cor 理由 void <2*1e9。
想打表的自行離開
題目描述
對於任何正整數x,其約數的個數記作g(x)。例如g(1)=1、g(6)=4。
如果某個正整數x滿足:g(x)>g(i) 0<i<x,則稱x為反質數。例如,整數1,2,4,6等都是反質數。
現在給定一個數N,你能求出不超過N的最大的反質數麽?
不能
題意:
求最小的x∈[1,N],使得x為 g(x)最大的數 中最小的一個。
1.x不會有超過10個不同質因子。理由:2*3*5...*31>2*1e9,2*3*5...*29<2*1e9。2~29質數剛好10個。
2.質因子指數不會大於30。理由:當取最小的質因子2時,231>2*1e9,230
3.若x=p1^c1*p2^c2...pn^cn,則x的因子個數為(c1+1)(c2+1)...(cn+1)。即:g(x)=(c1+1)(c2+1)...(cn+1)。
4.質因子連續、指數不升。理由:反證法。若x=p1^c1*p2^c2...pn^cn,且存在pn-1<p<pn,則x0=p1^c1*p2^c2...pn-1^cn-1*p^cn<x,g(x0)=g(x),不符合題意。
若存在cn>cn-1,則將cn,cn-1位置交換,也不符合題意
綜上所述,可以用上述幾個約束條件進行搜索剪枝。
代碼就是簡單的DFS。
#include<iostream> #include<vector> typedef long long ll; using namespace std; const ll pa[16]={0,2,3,5,7,11,13,17,19,23,29}; ll n,ans=1,g=0; void dfs(ll p,ll t,ll now,ll ng) { if(now>n) return; if(p>10) return; ll temp=ng; for(ll i=1;i<=t;i++){ now*=pa[p]; ng=temp*(i+1); if(now>n) return; if(ng>g) ans=now,g=ng; if(ng==g) ans=min(now,ans); dfs(p+1,i,now,ng); } } signed main() { cin>>n; dfs(1,30,1,1); cout<<ans; return 0; }
洛谷 P1463、POI2002、HAOI2007 反素數