思路:维护两个指针p和q,分别指向当前序列和sum所对应序列的起点和终点。若sum < N则q右移且sum增大;若sum > N则p右移且sum减小;若sum == N则输出p、q所指序列,然后q继续右移,如此循环。程序中止条件为q > (N+1)/2,原因是:若序列存在一个或多个大于等于(N+1)/2的元素,则其和必然大于N
代码:
void process(int n){
assert(n > 0);
int p = 1, q = 2;
int sum = p+q;
int exist = 0;
while(q <= (n-1)/2+1){ //避免溢出
while(sum != n && p != q){ //p == q时,已超过序列右界,程序中止
if(sum < n){
q++;
sum += q;
}
else{
sum -= p;
p++;
}
}
if(p != q){ //存在满足条件的序列
for(int i = p; i <= q; i++)
printf("%d ", i);
printf("\n");
q++; //找到满足条件的序列后,下一次让q右移,否则会死循环
sum += q;
exist = 1;
}
}
if(!exist) //不存在满足条件的序列
printf("-1\n");
}