多组输入,每组输入数据包括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语句中为假;