CodeForces - 27E--Number With The Given Amount Of Divisors(反素数)
Description
Given the number n, find the smallest positive integer which has exactly n divisors. It is guaranteed that for the given n the answer will not exceed 1018.
Input
The first line of the input contains integer n (1 ≤ n ≤ 1000).
Output
Output the smallest positive integer with exactly n divisors.
Sample Input
4
6
6
12
题解:反素数:
今天要我要讲的是反素数,在ACM中也算是常见的考点,那么对于搞ACM的同学来说,很有必要搞清楚它,所以接下
来我会很详细地讲解。
在讲解反素数之前,我们先来看反素数的概念。
反素数的定义:对于任何正整数,其约数个数记为,例如,如果某个正整数满足:对任意的正整
数,都有,那么称为反素数。
从反素数的定义中可以看出两个性质:
(1)一个反素数的所有质因子必然是从2开始的连续若干个质数,因为反素数是保证约数个数为的这个数尽量小
(2)同样的道理,如果,那么必有
在ACM竞赛中,最常见的问题如下:
(1)给定一个数,求一个最小的正整数,使得的约数个数为
(2)求出中约数个数最多的这个数
从上面的性质中可以看出,我们要求最小的,它的约数个数为,那么可以利用搜索来解。
以前我们求一个数的所有因子也是用搜索,比如,以每一个为树的一层建立搜索树,深度为
以为例进行说明,建树如下:
可以看出从根节点到每一个叶子结点这条路径上的所有数字乘起来都是12的约数,所以12有6个约数。
代码:
#include<iostream> #include<cstring> #include<cstdio> #include<cmath> #include<vector> #include<algorithm> using namespace std; const int INF=0x3f3f3f3f; const double PI=acos(-1.0); #define SI(x) scanf("%d",&x) #define SL(x) scanf("%lld",&x) #define PI(x) printf("%d",x) #define PL(x) printf("%lld",x) #define T_T while(T--) #define P_ printf(" ") typedef unsigned long long uLL; int prim[16]={2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53};//定义16个是因为这16个想乘正好超ull int n; uLL ans; void dfs(int pos,uLL v,int num){//注意v的类型。。。 if(num==n&&ans>v)ans=v; //if(num>n)return; for(int i=1;i<=63;i++){ if(num*(i+1)>n||v*prim[pos]>ans)break;//这里在于优化,要不要均可以; dfs(pos+1,v*=prim[pos],num*(i+1));//保证小的素数必须成才能保证值的小。。。 } } int main(){ while(~scanf("%d",&n)){ // printf("%llu\n",(uLL)2*3*5*7*11*13*17*19*23*29*31*37*41*43*47*53); ans=(uLL)~0; dfs(0,1,1); printf("%llu\n",ans); } return 0; }