• 【洛谷 P1147】连续自然数和 题解(等差数列求和+因式分解+解二元一次方程)


    连续自然数和

    题目描述

    对一个给定的正整数 M M M,求出所有的连续的正整数段(每一段至少有两个数),这些连续的自然数段中的全部数之和为 M M M

    例子: 1998 + 1999 + 2000 + 2001 + 2002 = 10000 1998+1999+2000+2001+2002 = 10000 1998+1999+2000+2001+2002=10000,所以从 1998 1998 1998 2002 2002 2002 的一个自然数段为 M = 10000 M=10000 M=10000 的一个解。

    输入格式

    包含一个整数的单独一行给出 M M M 的值( 10 ≤ M ≤ 2 , 000 , 000 10 \le M \le 2,000,000 10M2,000,000)。

    输出格式

    每行两个正整数,给出一个满足条件的连续正整数段中的第一个数和最后一个数,两数之间用一个空格隔开,所有输出行的第一个按从小到大的升序排列,对于给定的输入数据,保证至少有一个解。

    样例 #1

    样例输入 #1

    10000
    
    • 1

    样例输出 #1

    18 142 
    297 328 
    388 412 
    1998 2002
    
    • 1
    • 2
    • 3
    • 4

    思路

    差为1的等差数列求和
    (l + r)(r - l + 1) / 2 = m
    (l + r)(r - l + 1) = 2m

    将2m分解因数,得到若干组x1、x2
    l + r = x1
    r - l + 1 = x2

    解二元一次方程:
    l = x1 - r
    r = (x1 + x2 - 1) / 2


    AC代码

    #include 
    #include 
    #include 
    #define mp make_pair
    #define AUTHOR "HEX9CF"
    using namespace std;
    
    int main() {
        int m;
        vector<pair<int, int>> v, ans;
        cin >> m;
        // 因数分解
        for(int i = 2; i * i <= m * 2; i++) {
            if(2 * m % i) {
                continue;
            }
            if(i * i != m * 2) {
                v.push_back(mp(i, m * 2 / i));
                v.push_back(mp(m * 2 / i, i));
            } else {
                v.push_back(mp(i, i));
            }
        }
        for(auto &x : v) {
            int x1 = x.first;
            int x2 = x.second;
            // cout << x1 << " " << x2 << endl;
            if((x1 + x2 - 1) % 2) {
                continue;
            }
            int r = (x1 + x2 - 1) / 2;
            int l = x1 - r;
            if(l >= 0 && l <= r) {
                ans.push_back(mp(l, r));
                // cout << l << " " << r << endl;
            }
        }
        sort(ans.begin(), ans.end());
        for(auto &i : ans) {
            cout << i.first << " " << i.second << endl;
        }
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
  • 相关阅读:
    Mysql binlog的三种模式statement,row,mixed详解,以及无主键造成复制延时的测试
    C++ 继承多态的运用
    高云FPGA系列教程(8):ARM串口数据接收(中断和轮询方式)
    Java精进-20分钟学会mybatis使用
    进阶指针(四)—— 加强对指针,数组名,sizeof,strlen的理解
    认识进制
    结构型-代理模式
    科普达人丨漫画图解什么是 eRDMA?
    VTK 标注类Widget 文字标注 vtkCaptionWidget
    html中字体加粗
  • 原文地址:https://blog.csdn.net/qq_34988204/article/details/132832835