题目链接:HDU2058
题意:1-n 寻找子序列和为m
如果二重循环求sum很容易TLE,故有以下分析:
等差数列的求和公式:Sn=(a1+an)*n/2=(2*a1+(n-1)*d)*n/2
在此题中Sn=(2*a1+len)*(len+1)/2=m;
由此可得:a1=m/(len+1)+len/2;
由此可知m确定后len不可以随便取,其最大为sqrt(2*m) (取不到)
代码:
#include<iostream>
#include<cmath>
#include<cstdio>
using namespace std;
int main()
{
int n,m;
while(cin>>n>>m)
{
if(m==0&&n==0) break;
int len;int s;
len=(int)sqrt(2*m);
while(len--)
{
s=m/(len+1)-len/2;
if((2*s+len)*(len+1)/2==m)
printf("[%d,%d]
",s,s+len);
}
cout<<endl;
}
}