满足条件的数累加

GitHub跳转原题关系图返回列表

区间 [m, n] 内的 17 的倍数构成公差 17 的等差数列,定位首末项后 O(1) 求和。

OJ: roj

题目 ID: 1066

难度:入门

标签:数论等差数列入门

创建: 2026-07-05 21:47

更新: 2026-10-04 23:57

题目描述

给定两个正整数 m,nm,n(0<m<n<10000<m<n<1000),求区间 [m,n][m,n] 内所有能被 1717 整除的数之和。输入一行两个整数 m,nm,n,用一个空格隔开;输出一行,表示累加的结果。

样例输入 50 85,样例输出 204(51+68+8551+68+85)。

思路

区间内的 17 的倍数构成公差为 17 的等差数列:首项取 ≥m\ge m 的最小 17 的倍数,末项取 ≤n\le n 的最大 17 的倍数,项数 k=(last−first)/17+1k=(last-first)/17+1,答案为首末项平均乘项数。若首项大于末项,说明区间内无 17 的倍数,输出 0。

参考代码

Python 版:

python
#!/usr/bin/env python3
# Author by Rainboy blog: https://rainboylv.com github: https://github.com/rainboylvx
# rbook: -> https://rbook.roj.ac.cn  https://rbook2.roj.ac.cn
# rainboy的学习导航网站: https://idx.roj.ac.cn
# create_at: 2026-07-05 21:47
# update_at: 2026-07-05 21:47

import sys


def solve() -> None:
    data = iter(map(int, sys.stdin.buffer.read().split()))
    m = next(data)
    n = next(data)

    # 区间 [m, n] 中第一个能被 17 整除的数
    first = m if m % 17 == 0 else m + (17 - m % 17)

    # 等差数列求和:首项 first,末项 last,项数 k
    last = n - n % 17
    if first > last:
        print(0)
        return

    k = (last - first) // 17 + 1
    ans = (first + last) * k // 2
    print(ans)


if __name__ == "__main__":
    solve()

C++ 版(同一算法):

cpp
/**
 * Author by Rainboy blog: https://rainboylv.com github: https://github.com/rainboylvx
 * rbook: -> https://rbook.roj.ac.cn  https://rbook2.roj.ac.cn
 * rainboy的学习导航网站: https://idx.roj.ac.cn
 * create_at: 2026-10-04 23:57
 * update_at: 2026-10-04 23:57
 */

#include <iostream>
using namespace std;

typedef long long ll;

ll m, n;
ll first_term, last_term; // 区间 [m, n] 内 17 的第一个倍数、最后一个倍数
ll term_count;            // 等差数列的项数

int main() {
    cin >> m >> n;

    // 首项:>= m 的最小 17 的倍数
    if (m % 17 == 0) {
        first_term = m;
    } else {
        first_term = m + (17 - m % 17);
    }
    // 末项:<= n 的最大 17 的倍数
    last_term = n - n % 17;

    if (first_term > last_term) { // 区间内没有 17 的倍数
        cout << 0 << endl;
        return 0;
    }

    // 符合条件的数构成公差为 17 的等差数列,首末项平均后乘项数
    term_count = (last_term - first_term) / 17 + 1;
    cout << (first_term + last_term) * term_count / 2 << endl;

    return 0;
}