求1 - n当中约数个数最多的数,若有多解则输出最小的数。
一般解法:
从1到n枚举 根据
约数个数定理 公式求出约数个数
这需要先求出1到n的所有质数
以此来对第i个数分解质因数 质因数变化即 乘以 (上一个质因数个数+1)
对于n非常大时候效率很低
从图中可以看出 约数最多的数a
1. a中较小的质因数个数必定大于等于大一级的质因数个数
2. 随着a的递增 质因数的"种类"也按照质数的出现顺序递增
质数数组为prim(n) 则有
约数最多的数a = prim(0) ^ x0 + prim(1) ^ x1 + ...... + prim(n - 1) ^ x(n - 1)
a 的约数个数 = (x0 + 1) * (x1 + 1) * (x2 + 1) * ...... * (x(n - 1) + 1)
x0 >= x1 >= x2 >= x3 >= ...... >= x(n - 1)
#include <iostream>
using namespace std;
long nb; int mc;
int p[] = {2,3,5,7,11,13,17,19};
//d 素数深度 c素数次方限制 tot约数个数 num当前数 up上限值
void ss(int d, int c, int tot, long long num, long up)
{
if((tot > mc) || ((tot == mc) && (num < nb)))
{mc = tot; nb = num;}
if(d > 7) return;
long j = p[d], m = 1;
long long n = num * j;
while(m <= c && n <= up)
{
ss(d + 1, m, tot * (m + 1), n, up);
n *= j; m++;
}
}
int main()
{
int t; long n;
cin>>t;
while(t--)
{
cin >> n;
mc = nb = 1;
ss(0, 27, 1, 1, n);
cout << nb << " " << mc << endl;
}
}