一个正整数有可能可以被表示为n(109>=n>=2)个连续正整数之和,如:
15 = 1 + 2 + 3 + 4 + 5 15 = 4 + 5 + 6 15 = 7 + 8 \begin{aligned}&15=1+2+3+4+5 \\ &15=4+5+6 \\ &15=7+8\end{aligned} 15=1+2+3+4+515=4+5+615=7+8
根据输入的任何一个正整数,找出符合这种要求的所有连续正整数序列。
一个正整数 N N N 。
输出符合题目描述的全部正整数序列,每行一个序列,每个序列都从该序列的最小正整数开始、以从小到大的顺序打印。如果结果有多个序列,按各序列的最小正整数的大小从小到大打印各序列。此外,序列不允许重复,序列内的整数用一个空格分隔。如果没有符合要求的序列,输出 “NONE” 。
样例输入:(num.in)
15
样例输出:(num.out)
1 2 3 4 5 4 5 6 7 8
样例输入:(num.in)
16
样例输出:(num.out)
NONE
时间限制: 1 s 1 \text {s} 1s。
空间限制: 256 MB 256 \text {MB} 256MB。 【解析】 显然,输出的是一个等差数列,公差为1。 那么我们设它的首项为 a a a ,项数为 k k k ,则这个数列的末项为 a + k − 1 a+k-1 a+k−1。 根据题意可得, ( a + a + k − 1 ) × k 2 = n \frac{(a+a+k-1)\times k} {2}=n 2(a+a+k−1)×k=n移项得, 2 a k + k ( k − 1 ) = 2 n 2ak+k(k-1)=2n 2ak+k(k−1)=2n整理得, a = 2 n − k ( k − 1 ) 2 k a=\frac{2n-k(k-1)}{2k} a=2k2n−k(k−1) 如此一来,我们可以知道, ( 2 n − k ( k − 1 ) ) ∣ 2 k (2n-k(k-1))|2k (2n−k(k−1))∣2k,且 a > 0 a>0 a>0 ,因此,我们只要枚举 k k k 就好了,那么它的范围是多少呢? 刚才说了, a a a 是大于 0 0 0 的,而 k k k 又是正整数,所以, 2 n − k ( k − 1 ) > 0 2n-k(k-1)>0 2n−k(k−1)>0即 k 2 + k < 2 n k^2+k<2n k2+k<2n则 k 2 必 然 是 小 于 2 n 的 k^2 必然是小于 2n的 k2必然是小于2n的 接下来的就不用多说了,直接上代码吧ヽ( ̄▽ ̄)ノ当然,如果无解不要忘记输出 NONE ! 【代码展示】
#include<bits/stdc++.h> #define ud using namespace std #define itn int #define ll long long ud; int n; bool flag=0; inline long long read() { long long sum=0,flag=1; char c; for(;c<'0'||c>'9';c=getchar())if(c=='-') flag=-1; for(;c>='0'&&c<='9';c=getchar())sum=(sum<<1)+(sum<<3)+c-'0'; return sum*flag; } int main() { n=read(); for(int k=sqrt(2*n);k>=2;--k) { if((2*n-k*(k-1))%(2*k)==0) { int a=(2*n-k*(k-1))/(2*k); printf("%d",a); for(int j=a+1;j<=a+k-1;++j) printf(" %d",j); printf("\n"); flag=1; } } if(!flag) printf("NONE\n"); return 0; }