题意:给定整数N和整数M,求在1~N之间和等于M的子序列,然后输出此区间左右边界。
解题思路:起初准备开数组打表,可数据太大,然后就没思路了,于是就上网搜一下绝大多数用的都是等差数列,即设以a为起始点的区间且长度为len,该区间可写成a+1,a+2,.....
a+len,然后利用等差数列的求和公式计算:M = (a +1+ a + len ) * len / 2,得出a = M/len - (len+1)/2。对于len的初始值计算为:当a=0时,M=(len+1)*len/2,可得len*len < 2*M,取值时 len = sqrt(2.0*M)+1,详见代码:
Code:
#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
int main()
{
int N,M,len,a;
while(scanf("%d%d",&N,&M) && N&&M)
{
len = sqrt(2.0*M)+1;
while(--len)
{
a = M/len - (len+1)/2;
if((a+a+len+1)*len/2 == M)
printf("[%d,%d]\n",a+1,a+len);
}
printf("\n");
}
return 0;
}