您的位置:首页 > 其它

高合成数(反素数)

2015-11-26 14:37 351 查看
做题的时候用到了高合函数,也叫反素数,折腾了好几天,总算是懂了那么一点。

先说说高合函数的定义:

对于任何正整数n,其约数个数记为f(n),例如f(1)=1,f(6)=4.如果某个正整数n满足:对任意的正整数i,都有f(i)<f(n),那么称n为高合函数。

高合函数有很好的性质,首先:一个反素数的质因子必然是从2开始连续的质数,其次,num=2^t1*3^t2*5^t3*7^t4.....必然t1>=t2>=t3>=t4>=....

重点来了!!

求一个高合函数,其根本是求一个数的所有约数,而定理有:一个数约数个数=所有素因子的次数+1的乘积。

并且,小素因子多的数一定比大素因子多的数要小,这样我们就可以用搜索求解,第一层素数是2,第二层素数是3.

..以此类推。

下面的代码的题目:给一个数

,求一个最小的正整数,使得它的因子个数为

。(并不完全是高合函数,但稍加修

改即可)(不是每个约数都有反素数的)

#include<stdio.h>
#define MAX_PRIME 60
#define MAX_ANTIPRIME 50
#define MAX 0x7fffffff
#define ll long long
int prime[MAX_PRIME];
void init_prime();
void dfs(int level,ll temp,int time);
int min;
int n;
int main(){
init_prime();
/*for(int i=0;i<20;i++){
printf("%d\n",prime[i]);
}*/
scanf("%d",&n);
min = MAX;
dfs(0,1,1);
printf("%d\n",min);

return 0;
}
//level:当前的素数数组的位置 prime[level]   temp:当前计算到的数   time:当前约数的个数
void dfs(int level,ll temp,int time){
if( time>n || temp>min ){
return ;
}
if(time==n&&min>temp){
min = temp;
return;
}
for(int i=0;i<MAX_ANTIPRIME;i++){
if(min<temp*prime[level]){  //剪枝,当当前计算的数与本次素数的乘积大于已求得的最小数,则不需计算了
break;
}   //level+1进入下一个素数
dfs(level+1,temp*=prime[level],time*((i+1)+1));  //time根据定理,time=所有素因子的次数+1的乘积
}   //注意temp每乘一次 ,都需要变化,当前这一层是计算共有几个prime[level]素数
}

void init_prime(){  //计算素数
prime[0] = 2;
prime[1] = 3;
int time = 2;
for(int i=5;time<MAX_PRIME;i+=2){
int status = 0;
int j=1;
for(;j<time&&prime[j]*prime[j]<=i;j++){
if((i%prime[j])==0){
status = 1;
break;
}
}
if(status == 0){
prime[time++] = i;
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: