The sum problem
Given a sequence 1,2,3,…N, your job is to calculate all the possible sub-sequences that the sum of the sub-sequence is M.
Input
Input contains multiple test cases. each case contains two integers N, M( 1 <= N, M <= 1000000000).input ends with N = M = 0.
Output
For each test case, print all the possible sub-sequence that its sum is M.The format is show in the sample below.print a blank line after each test case.
Sample Input
20 10
50 30
0 0
Sample Output
[1,4]
[10,10]
[4,8]
[6,9]
[9,11]
[30,30]
批注
不可使用暴力枚举,会超时,应从等差数列求和的公式下手,先找到最大的长度
AC代码
#include <stdio.h>
#include <math.h>
int main(void)
{
long long n, m, i, h, k;//假设所求区间为[k,h];
while(scanf("%lld%lld",&n,&m) != EOF){
if(n == 0 && m == 0){
break;
}
for(i = sqrt(2 * n); i > 0; i --){//那么假设i为区间的长度即从k到h的长度
k = ( 2 * m / i + 1 - i ) / 2;//根据等差数列前n项和公式(首项+末项)乘于a(区间长度)再除于2就等于m了(即:(((j+i)*a)/2=m))因为这里等差为1所以i=j+a-1 ==> ((j+a-1+j)*a)/2=m ==> j=(2*m/a+1-a)/2所以这里直接暴力枚举就OK了
h = k + i - 1;
if(k == 0) continue;
if(m == i * k + i * (i - 1) / 2){
printf("[%lld,%lld]\n", k, h);
}
}
printf("\n");
}
return 0;
}