对一个给定的正整数 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 10≤M≤2,000,000)。
每行两个正整数,给出一个满足条件的连续正整数段中的第一个数和最后一个数,两数之间用一个空格隔开,所有输出行的第一个按从小到大的升序排列,对于给定的输入数据,保证至少有一个解。
10000
18 142
297 328
388 412
1998 2002
差为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
#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;
}