题目大概:给出一个闭区间,问该闭区间内哪个数的因数最多,有多少个,若出现并列输出最小的
题目链接:https://vjudge.net/problem/UVA-294
思路:
根据唯一分解定理,每个正整数 X 的因数个数可以套用公式:
(e1 + 1) * (e2 + 1) * ..* (ek + 1)
其中k为X的质因数个数,ei 为完全分解后第 i 个质因数的指数
那么问题就简单多了,求出质因数及其指数,代入公式计算即可,还有一些小问题:
1.如果分解不彻底,即分解后X不为1,那么当前的 X 是一个较大素数,返回ans * (1 + 1)
2.如果不求速度不打表也是可以的,打表的话取到32000就够用了,两种解法均给出
3.注意输出规格,不同取大,同取小
4.其他细节见代码:
代码×2:
/-这是第一次写的代码 打表
/-Time 10 ms
#include <cstdio>
#include <cmath>
#include <iostream>
using namespace std;
const int maxn = 32000;
int pt[maxn];
int p[maxn];
int cnt;
/* 1 ≤ L ≤ U ≤ 1000000000 and 0 ≤ U - L ≤ 10000 */
void prime_table_make() {
int tt = sqrt(maxn + 0.5);
for(int i = 2; i <= tt; i++)
if(!pt[i]) for(int j = i * i; j <= maxn; j += i) pt[j] = 1;
for(int i = 2; i <= maxn; i++)
if(!pt[i]) p[cnt++] = i;
}
int F (int x) {
int ans = 1;
for(int i = 0; i < cnt; i++) {
int t = p[i];
if(x%t == 0) {
int e = 0;
while(x%t == 0) {e++; x /= t;}
ans *= e+1;
}
if(x == 1) break; //提前结束 夜长梦多
}
if(x>1) ans*2;/* Now_x is a Big_prime */
return ans;
}
int main() {
prime_table_make();
int T,L,U; cin>>T;
while(T--) {
cin>>L>>U;
int ans = 0, abx;
for(int i = L; i <= U; i++) {
int t = F(i);
if(t > ans) {
ans = t;
abx = i;
}
}
printf("Between %d and %d, %d has a maximum of %d divisors.\n", L, U, abx, ans);
}
return 0;
}
/-这里只给出了核心代码 不打表解法
/-Time 70 ms
int part (int x) {
int ans = 1, sqr = sqrt(x + 0.5); //double.
for(int i = 2; i <= sqr; i++) {
if(x%i == 0) {
int t = 0;
while(x%i == 0) {
x /= i;
t++;
}
ans *= t+1; //()
}
if(x == 1) break;
}
if(x > 1) return ans * 2; //Now x is a Big_Prime.
return ans;
}
int main() {int T; cin >> T; getchar();
int a, b;
while(T--) {
scanf("%d%d", &a, &b);
printf("Between %d and %d, ", a, b);
int it, tmp, ans = 0;
for(; a <= b; a++) {
tmp = part(a);
if(tmp > ans) ans = tmp, it = a;
}
printf("%d has a maximum of %d divisors.\n", it, ans);
}
return 0;
}