Divisors UVA - 294(唯一分解定理 + 筛法)

题目大概:给出一个闭区间,问该闭区间内哪个数的因数最多,有多少个,若出现并列输出最小的

题目链接: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;
}
发布了54 篇原创文章 · 获赞 43 · 访问量 1944

猜你喜欢

转载自blog.csdn.net/Jungle_st/article/details/104703941