世界真的很大
数的本质之类的东西,唯一分解定理
除了通过一个数来分解得到素数的唯一分解,通过枚举素数来反推原数也是常用的做法。
写的时候还是要注意细节,数论什么的一定要从数本身入手
讲道理其实解法最后和数论没有什么关系也没有什么关系
看题先:
description:
对于任何正整数x,其约数的个数记作g(x)。例如g(1)=1、g(6)=4。如果某个正整数x满足:g(x)>g(i) 0
input:
一个数N(1<=N<=2,000,000,000)。
output:
不超过N的最大的反质数。
在一定范围内最大的反素数
仔细分析一下,反素数的因数个数必须要比比他小的数的个数多。
最大的反素数就是说,在这个区间内比他大的数的数的因数个数不会比他多,不然他就不是最大的了
比他小的数里面,也不会有数的因数比他多,因为他是“反素数”
即我们需要找的,就是在这样一个范围内,拥有最多素数个数的数
看到一个数的约数个数,一般能想到的就是这个约数个数定理吧:
然后这个约数个数定理是在一个数唯一分解之后才有的
而且发现质数的叠加的话最多也才12个就超过范围了
那我们直接枚举每一个质数的指数,来DFS暴力搜索就好
有一个剪枝是,大的质数的指数一定比小的质数的指数小,一个贪心的思想吧?
完整代码:
#include<stdio.h>
#include<algorithm>
using namespace std;
typedef long long dnt;
dnt n,ans=0,bns=0;
dnt p[13]={1,2,3,5,7,11,13,17,19,23,39,31};
void dfs(int state,dnt num,dnt tot,int last)
{
if(num>n) return ;
if(state==12)
{
if(tot>bns) bns=tot,ans=num;
else if(tot==bns) ans=min(ans,num);
return ;
}
dnt rt=1;
for(int i=0;i<=last;i++)
{
dfs(state+1,num*rt,tot*(i+1),i);
rt*=p[state];
}
}
int main()
{
scanf("%lld",&n);
ans=n;
dfs(1,1,1,20);
printf("%lld\n",ans);
return 0;
}
/*
EL PSY CONGROO
*/
嗯,就是这样