最多约数问题
正整数x的约数是能整除x的正整数。正整数x 的约数个数记为div(x)。例如,1,2,5,10 都是正整数10 的约数,则div(10)=4。设a 和b 是2 个正整数,a≤b,找出a和b之间约数个数最多的数x的约数个数.
输入
输入只有一行为两个整数a, b
输出
输出只有一行为a和b之间约数个数最多的数x的因数个数.
示例输入
1 36
示例输出
9
示例输入
1000 800000
示例输出
240
o(n*n^1/2)n的根号n 质因数分解算法
#include<bits/stdc++.h>using namespace std;int a, b;int div(int x) {unordered_map<int, int> maps;while (x % 2 == 0) {maps[2]++;x /= 2;}for (int i = 3; i * i <= x; i += 2) {while (x % i == 0) {maps[i]++;x /= i;}}if (x > 2) maps[x]++;int sum = 1;for (auto p : maps) {sum *= (p.second + 1);}return sum;
}int main () {int a, b, ans = 0;cin >> a >> b;for (int i = a; i <= b; i++) {ans = max(ans, div(i));}cout <<ans << endl;
}//by wqs
一个合数的约数个数等于它每个质因数的个数+1再相乘。
例如10分解为10=2^1 * 5^1;
则10的约数可以选择0个2,0个5对应1;1个2,0个5,对应2;0个2,1个5对应5;1个2,1个5对应10;
事实上10的约数个数=所有(质因数次数 + 1)的乘
10的约数就是4
例如12=2^2 * 3^1;
可以选择0个2,1个2,2个2,0个3,1个3
一共有(2 + 1)*(1 + 1)种选择
12的约数就是6
质因数分解
时间复杂度o(n^1/2)也就是根号n
unordered_map<int, int> maps;
while (x % 2 == 0) {maps[2]++;x /= 2;
}
for (int i = 3; i * i <= x; i += 2) {while (x % i == 0) {maps[i]++;x /= i;}
}
if (x > 2) maps[x]++;
求约数
int sum = 1;
for (auto p : maps) {sum *= (p.second + 1);
}
return sum;
统计最大约数
for (int i = a; i <= b; i++) {ans = max(ans, div(i));
}
0(nln(n)) 埃拉托斯特尼筛法,最佳算法
#include<bits/stdc++.h>using namespace std;int a, b, ans = 0;int main() {cin >> a >> b;vector<int> div_count(b + 1, 0);for (int i = 1; i <= b; i++) {for (int j = i; j <= b; j += i) {div_count[j]++;}}for (int i = a; i <= b; i++) {ans = max(ans, div_count[i]);}cout << ans << endl;return 0;
}//by wqs
很好理解
i=1时把能整除1的数div++,例如1,2,3,4,5,6,7,8,…
i=2时把能整除2的数div++,例如2,4,6,8,10,12,…
i=3时把能整除3的数div++,例如3,6,9,12,…
i=101时把能整除101的数div++,例如101,202,303,404…
for (int i = 1; i <= b; i++) {for (int j = i; j <= b; j += i) {div_count[j]++;}
}
最后统计既可
for (int i = a; i <= b; i++) {ans = max(ans, div_count[i]);
}