多组输入,每组输入数据包括m,n

n表示数列的长度,需要在这段数列中找到一段数列相加等于m,输出所有符合的序列

#include<iostream>
#include<cmath>
using namespace std;
int main()
{
    long long m, n;
    while(cin >> n >> m, m||n){
        long long a, k;
        for(k=(int)sqrt(m*2); k>0; k--){
            a=m/k-(k-1)/2;
            if((a+a+k-1)*k==m*2){
                printf("[%lld,%lld]\n", a, a+k-1);
            }
        }
        printf("\n");
    }
    return 0;
}

本题难点

1 k值

k值为所求序列最大长度

设1+2+..+k=m;

由求和公式(1+k)*k/2=m

得到k<sqrt(m*2);

所以所求序列长度最长为k

2 a值

这里面a是首项的值,尾项是a+k-1;

由求和公式(a+a+k-1)/2=m;

得到a=m/k+(k-1)/2;

3.为什么加if()

因为a求出来可能是小数,而题目中要求的是整数,所以只有a是整数的时候if()语句才是真,如果a是小数会被截断导致if语句中为假;