top1编程
← 返回题目
题解

因数

1 条题解

  • 0
    @ 2026-8-5 23:59:33

    P4707 因数(入门)

    解题思路

    第一步:看懂题目。 要找一个最小的正整数 N,使得“N 除以 A 再向上取整”的结果大于等于 I。

    第二步:学会“向上取整”。 向上取整就是:算出来的结果如果不是整数,就取比它大的最小整数。比如 23.3 向上取整是 24,0.125 向上取整是 1。在编程里,N 除以 A 向上取整可以写成 (N + A - 1) / A。这个公式为什么对呢?因为 N 除以 A 的余数最小是 0、最大是 A-1:如果余数是 0,加上 A-1 后仍不够一个整倍,整除结果不变;如果余数至少是 1,加上 A-1 后一定越过一个整倍,结果正好多 1。

    第三步:用题目要求的枚举算法。 题目特别要求用枚举算法:从 N=1 开始,一个一个往上试,第一个让 (N + A - 1) / A ≥ I 的 N 就是答案。

    第四步:举个例子验证。 A=38、I=24。N 从 1 开始试,试到 N=875 时:(875+37)/38=912/38=24,正好 ≥24;而 N=874 时 (874+37)/38=911/38=23,不够。所以答案是 875,和样例一致。

    第五步:枚举到什么时候为止? 最多枚举到 (I-1)×A+1 就一定会满足,因为 (I-1)×A+1 除以 A 向上取整正好是 I。由于 A、I 最大只有 100,枚举次数最多一万次左右,完全来得及。

    第六步:注意边界情况。 A=1 时,任何 N 除以 1 向上取整都是 N,所以答案是 I;I=1 时,N=1 就满足条件,答案就是 1。

    参考代码

    // 因数:用枚举法找最小 N,使 N/A 向上取整后大于等于 I
    #include <iostream>
    using namespace std;
    
    int main() {
        int divisor, target;
        cin >> divisor >> target;
        for (int num = 1; ; num++) { // 从小到大枚举 N
            // (num + divisor - 1) / divisor 是 num/divisor 的向上取整结果
            if ((num + divisor - 1) / divisor >= target) {
                cout << num << endl;
                break; // 找到最小的 N 就结束
            }
        }
        return 0;
    }
    

    复杂度分析

    从 1 枚举到答案,最多约 (I-1)×A+1 次,A、I ≤ 100 时最多一万次,时间复杂度 O(I×A)。只用了几个变量,空间 O(1)。

    • 1