传送门
思路:
爆搜好题,hack好题(?)
程序最后附带三组数据……
暴力搜索有哪些质因子
比较重要的一个是n最多只有一个大于
n√
的质因子
也就是我们只用找所有小于等于
n√
的质因子就可以了
每次判断一下,如果当前的x大于
n√
且是质数,那么直接乘到答案中去就可以了
加上各种的剪枝优化……
话虽这么说但细节还是蛮多的
话说我hack了好几个人……
代码:
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<iostream>
#define LL long long
using namespace std;
int goal;
LL ans=1LL<<60;
int prime[100005];
bool vis[100005];
void init()
{
for (int i=2;i<=47000;++i)
{
if (!vis[i]) prime[++prime[0]]=i;
for (int j=1;j<=prime[0];++j)
{
if (prime[j]*i>47000) break;
vis[prime[j]*i]=1;
if (i%prime[j]==0) break;
}
}
}
bool cal(LL x)
{
for (int i=1;i<=prime[0]&&(LL)prime[i]*prime[i]<=x;++i)
if (x%prime[i]==0) return 0;
return 1;
}
void dfs(LL n,LL x,int p)
{
if (n>=ans||(n>=(1LL<<31))||p>prime[0]) return;
if (x==1)
{
ans=min(n,ans);
return;
}
if (x>sqrt(goal)&&cal(x+1))
{
ans=min(n*(x+1),ans);
return;
}
if (n*prime[p]>=ans) return;
LL t=1,ph=1;
for (int i=p;i<=prime[0];++i)
{
if (x<prime[i]-1) break;
if (x%(prime[i]-1)==0)
{
ph=prime[i]-1;
t=prime[i];
dfs(n*t,x/ph,i+1);
ph*=prime[i];t*=prime[i];
while (x%ph==0)
dfs(n*t,x/ph,i+1),
t*=prime[i],ph*=prime[i];
}
}
}
main()
{
scanf("%d",&goal);
init();
dfs(1,goal,1);
printf("%d\n",ans>=(1LL<<31)?-1:ans);
}
/*
1021870080
1021943953
2147483646
2147483647
1610547200
2139008425
*/