简单的求和题
2016-03-08 22:07
337 查看
The sum problem
Problem DescriptionGiven 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.
[align=left]Input[/align]
Input contains multiple test cases. each case contains two integers N, M( 1 <= N, M <= 1000000000).input ends with N = M = 0.
[align=left]Output[/align]
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.
[align=left]Sample Input[/align]
20 10
50 30
0 0
Sample Output
[1,4] [10,10] [4,8] [6,9] [9,11] [30,30]
【解析】
首先,这是一道很简单的题,我们不必被1<= N, M<=1000000000这个条件吓到,当然,如果你要想通过暴力的方式解出这道题,条件1<=N,M<=1000000000所限制,即会出现超时的!通过题意我们可以知道这是一个求子序列和的问题,然后子序列求和是不是很容易让我们想到等差数列求和公式了,是的,这道题就是使用等差数列求和公式来解决它的,等差数列求和公式:
,这个公式变形可得:2 * Sn = 2 * n * a1 + n * (n - 1) * d,a1 = Sn / n - (n - 1) / 2;;又因为1+2+……+(2*Sn)^1/2>Sn,所以和为Sn的元素个数n应该小于等于(2*Sn)^1/2;然后我们就可以通过公式计算出首相了,及a1,接下来的过程就顺水推舟了,请直接移步代码吧。
【代码】
#include <iostream>
#include <cmath>
using namespace std;
int main()
{
__int64 N, M, a1, n;
while(cin >> N >> M)
{
if(N == 0 && M == 0)
break;
for( n = (__int64)sqrt(2.0 * M); n > 0; n--)
{
a1 = M / n - (n - 1) / 2;
if(2 * a1 * n + n * (n - 1) == 2 * M)
cout << '[' << a1 <<',' << a1 + n - 1<< ']' << endl;
}
cout << endl;
}
return 0;
}