Codeforces 27E. Number With The Given Amount Of Divisors

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 1e18.

Input

The first line of the input contains integer n (1 ≤ n ≤ 1000).

Output

Output the smallest positive integer with exactly n divisors.

题目大意:

给定一个数字n,找到具有n个因子的最小整数.

思路:

由于答案达到了1e18,因此不可以暴力。

考虑到质因子分解定理,最后的答案肯定能分解成,而n等于

题目要求找到最小的ans,我们贪心的选取两个数a和b,保证这两个数的n值相同,则局部最优解一定会在min{a,b}中诞生,而两个数中较小的那个数有什么特点呢?

举个例子:12和18存在相同的n,但是,而,注意到指数的选择上有所不同,前者是2 2 3,后者是2 3 3,而答案显而易见是12.由此可见,如果n相同,那么指数的底数要尽可能小。

于是想到了:我们可以从底数2开始枚举指数,然后往下搜索新的质数底数,更新当前的因子数与n比较,然后更新最小值即可。

#include<bits/stdc++.h>
#define int long long
#define rd(x) scanf("%lld",&x)
#define put(x) printf("%lld",x)
#define YES "YES"
#define NO "NO"
#define Yes "Yes"
#define No "No"
#define mod 1000000007
#define MAX 2147483647
#define MIN -MAX 
using namespace std;
const int N = 2e5+5;
int ans= ((int)1<<62);
int prime[30]={2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53};
void dfs(int depth,int temp,int num,int po,int n){
    //之所以素数选到53,是因为当底数枚举到53的时候,此时的答案值已经到达数据范围了
    //为什么会到达数据范围?
    //每次枚举后面的底数,他的指数一定会小于前面的素数的指数
    //可以像12和18的例子一样转移指数的位置

    //当前数字的指数已经超过n了,跳过
    if(depth>=16 || num>n){
        return;
    }
    //更新最小ans
    if(num==n && temp<ans){
        ans=temp;
        return;
    }
    //枚举当前底数的指数
    for(int i=1;i<=po;i++){
        //剪枝,若新数字已经大于当前最小值,则不需要继续下去了;
        //因为继续下去的答案一定也会大于当前最小值
        if(temp * prime[depth]>ans){
            break;
        }
        temp = temp*prime[depth];
        dfs(depth+1,temp,num*(i+1),i,n);
    }
}
void solve(int n){
    dfs(0,1,1,64,n);
}
signed main(){
    int T=1;
//    rd(T); 
    while(T--){
        int n;
        rd(n);
        solve(n);
        cout<<ans;
    }
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值