洛谷 P1221 最多因子數(搜尋)
阿新 • • 發佈:2018-12-10
題目描述
數學家們喜歡各種型別的有奇怪特性的數。例如,他們認為945是一個有趣的數,因為它是第一個所有約數之和大於本身的奇數。
為了幫助他們尋找有趣的數,你將寫一個程式掃描一定範圍內的數,並確定在此範圍內約數個數最多的那個數。不幸的是,這個數和給定的範圍的都比較大,用簡單的方法尋找可能需要較多的執行時間。所以請確定你的演算法能在幾秒內完成最大範圍內的掃描。
輸入輸出格式
輸入格式:
只有一行,給出掃描的範圍,由下界L和上界U確定。滿足2≤L≤U≤1000000000。
輸出格式:
對於給定的範圍,輸出該範圍內約數個數D最多的數P。若有多個,則輸出最小的那個。請輸出“Between L and U,P has a maximum of D divisors.”,其中L,U,P和D的含義同前面所述。
輸入輸出樣例
輸入樣例#1: 複製
1000 2000
輸出樣例#1: 複製
Between 1000 and 2000, 1680 has a maximum of 40 divisors.
PS:其實就是找因子數最多的數,根據一個數都能被多個質因子分解,例如 p=a1^p1+a2^p2+……+an^pn.ai表示質數,pi表示該數字內有pi個ai,他的因子數sum就是sum=(p1+1)*(p2+1)*……*(pn+1)。除了131074,他有個質因子大於100,其他所有數的因子都小於100,所以只需要特判131074,其他都直接用dfs質因子跑質因子數目就行了。
#include <iostream> #include<cstring> #include<cstdio> #include<algorithm> #include<map> #include<queue> #include<set> #include<cmath> #include<stack> #include<string> const int maxn=5e5+10; const int mod=1e9+7; const int inf=1e8; #define me(a,b) memset(a,b,sizeof(a)) #define lowbit(x) x&(-x) typedef long long ll; using namespace std; ll l,r,ans,sum; ll s[30]={0,2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,91,97},p[30]; void check(ll s) { ll res=1; for(int i=1;i<=26;i++) res*=(p[i]+1); if(res>sum) sum=res,ans=s; else if(res==sum) ans=min(s,ans); } void dfs(ll sum,int st) { if(sum>r) return ; else if(l<=sum&&sum<=r) check(sum); for(int i=st;i<=26;i++) { p[i]++; dfs(sum*s[i],i); p[i]--; } } int main() { cin>>l>>r; if(l==r&&l==131074) printf("Between 131074 and 131074, 131074 has a maximum of 4 divisors.\n"); else { dfs(1,1); printf("Between %lld and %lld, %lld has a maximum of %lld divisors.\n",l,r,ans,sum); } return 0; }