链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1562
题意:给出一个n,求出n以内最小的数满足这个数的因数个数最多。
思路:要引进一个概念:反素数。
对于任何正整数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>=....
然后开始搜索,以上两个性质用来进行剪枝。

#include<cstdio> #include<iostream> #include<cstdlib> #include<cstring> #include<cmath> #include<vector> #include<set> #include<map> #include<algorithm> #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 using namespace std; typedef long long LL; const double PI=acos(-1); const int inf=0x3f3f3f3f; const double eps=1e-10; const int maxn=100; int prime[16]={1,2,3,5,7,11,13,17,19,23,29,31,37,41,43,47}; LL n,ans,maxs; void dfs(LL num,int k,LL sum,int limit) {//num当前的数,k枚举到第k个素数,sum当前num的约数个数,limit银子个数上限 if(sum>maxs) { ans=num; maxs=sum; } if(sum==maxs && ans>num) ans=num;//求最小的数 if(k>15) return; LL temp=num; for(int i=1;i<=limit;i++) //枚举每个质因子的个数 { if(temp*prime[k]>n) break; temp*=prime[k]; dfs(temp,k+1,sum*(i+1),i); } } int main() { while(~scanf("%lld",&n)) { ans=n,maxs=0; dfs(1,1,1,50); printf("%lld ",ans); } return 0; }
诶,好久没写搜索了,都不会写了。。。