33,010
社区成员
发帖
与我相关
我的任务
分享
int count(int n)
{
int i = 1;
int res = 0;
for ( ; i * i <= n; ++i)
{
if (n % i == 0)
res += 2;
}
if ((i - 1) * (i - 1) == n)
res -= 1;
return res;
}
这个函数的作用是:已知num有tot个因子,并且原区间为[num*low,num*up],求从from个素数开始,原区间内的数可以分解到的最多的约数
void search(long from, long tot, long num, long low, long up)
{
if (num >= 1)
if ( (tot > max) || ((tot == max) && (num < numb)) )
{
max = tot;
numb = num;
}
if ((low == up) && (low > num)) search(from, tot*2, num*low, 1, 1);
这句其实可以去掉,只是为了提高效率,当满足条件时,可以预见tot至少可以达到2倍的tot,且num*low就是这个数,这里的调用只是更新max和numb的值
for (long i = from; i <=PCOUNT; i++)
{
if (prim[i] > up) return;
else
{
long j = prim[i], x = low - 1, y = up, n = num, t = tot, m = 1;
while (true) //区间里数的分解可以分为带j的和不带j的,这里处理带j的情况
{
m++;
t += tot;
x /= j;
y /= j; //这里每除一次j,表示分解出一个j来
if (x == y) break; //说明区间[x,y]中的数没有j的倍数了
n *= j;
search(i+1, t, n, x+1, y); //带j的分解又可以按j的次数来分类,这里m-1为当前分解中j的次数,然后递归调用
}
m = 1 << m;
if (tot < max / m) return; //这里处理分解不带j的,进行下一次循环前先估计一下当前的分解有没有可能达到已经求得的最优解,否则没必要继续下去
}//end else
}//end for
}