题目描述
对一个给定的正整数 ,求出所有的连续的正整数段(每一段至少有两个数),这些连续的自然数段中的全部数之和为
。
例子:,所以从
到
的一个自然数段为
的一个解。
输入格式
包含一个整数的单独一行给出 的值(
)。
输出格式
每行两个正整数,给出一个满足条件的连续正整数段中的第一个数和最后一个数,两数之间用一个空格隔开,所有输出行的第一个按从小到大的升序排列,对于给定的输入数据,保证至少有一个解。
样例
样例输入
10000
样例输出
18 142
297 328
388 412
1998 2002
一开始怀着侥幸心理打了个暴力,没想到直接 了。
而且 ms
太水。
思路
直接把所有区间的左右端点枚举一遍,然后用等差数列公式求和就行:
如果当前区间
中所有元素的和等于
,输出答案
如果当前区间
中所有元素的和大于
,再往后枚举的区间和一定越来越大,因此果断退出循环
不开 虽然慢了一点,但也能过,总之
永远的神!
完整代码
#include<bits/stdc++.h>
using namespace std;
template<typename T> //使用模板类实现的快读
inline void read(T &x){ //可以兼容int/long long
x=0;char ch=getchar();
while(!isdigit(ch)) ch=getchar();
while(isdigit(ch)){
x=x*10+(ch^48);ch=getchar();
}return;
}
int main()
{
int m;register int i,j; //加register听说更快一点
read(m);
for(int i=1;i<=m-1;i++){
for(int j=i+1;j<=m;j++){
if((i+j)*(abs(i-j)+1)/2==m) printf("%d %d\n",i,j);
else if((i+j)*(abs(i-j)+1)/2>m) break;
//如果得出的和已经大于m,那么继续计算和就越来越大,
//更不可能等于m,所以直接结束这层循环
}
}
return 0;
}
等差数列公式:( 首项 末项 )
项数
-------------------------------------------------------请-------------------勿-------------------抄-------------------袭-------------------------------------------------------