hdu4228 (反素数)

题意:给你一个数N,找出一个最小的可以拆分成N种乘积表达形式的数x
Sample Input
2
16
19
0

Sample Output
4
840
786432

思路:比如N=2,6可以拆成2x3或者1x6两种,但不是最小的,最小的是4可以拆成1x4,2x2两种

首先可以肯定的是x必然有N*2或者是N*2-1(完全平方的情况)个约数

利用求反素数的过程求出约数为N*2和N*2-1个的最小的数
代码:

#include<stdio.h>
typedef __int64 LL;
const LL INF=((LL)1<<62)+1; 
int k;
__int64 p[100]={1,2,3,5,7,11,13,17,19,23,29,31,37,41,43,47};
__int64 ans;
void dfs(__int64 t,int sum,int pos,int limit,int k)
{
    if(sum==k&&ans>t)
    {
        ans=t;
    }
    if(pos>15)
        return;
    if(sum>=k)
        return;
    for(int i=1;i<=limit;i++)
    {
        if(t>ans/p[pos]||sum*(i+1)>k)
            break;
        t=t*p[pos];
        dfs(t,sum*(i+1),pos+1,i,k);
    }
}
int main()
{
    int n;
    while(scanf("%d",&n),n)
    {
        int nn;
        k=n*2;
        ans=INF;
        dfs(1,1,1,62,k);
        __int64 bestans=ans;
        ans=INF;
        dfs(1,1,1,62,k-1);
        if(bestans>ans)
            bestans=ans;
        printf("%I64d\n",bestans);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值