The sum problem
Time Limit: 5000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 14190 Accepted Submission(s): 4259
Problem Description
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]
这题的大致意思就是给你两数,第一个是有多少项,第二个是和,问题要求是你要在这多少项中找到子数列使得和为第二个数,
就像你输入20 10;输出的结果是【1,4】1+2+3+4=10,【10,10】10=10;
所以你只需要找到这个数列的开始和结尾就好了,开始我用双层循环,没有异议的超时了,八嘎!
代码:
好吧我承认我水,然后看了大神们的代码,才知道用等差数列公式变形做
Sn=(a1+aN)*n/2
=(a1+a1+d(n-1))*n/2
=a1*n+d(n-1)*n/2;
然后 a1=1,现在又可化简为Sn=n+(n-1)*n/2=(n+1)n/2;
由题意得M=Sn,N为项的个数,则N<=n(max)=sqrt(Sn*2)=sqrt(M*2);
因此原式M=Sn =a1*n+(n-1)n/2=a1*N+(N-1)N/2,可得a1*N=M-(N-1)N/2;
好吧这就可以做了;
代码:
就像你输入20 10;输出的结果是【1,4】1+2+3+4=10,【10,10】10=10;
所以你只需要找到这个数列的开始和结尾就好了,开始我用双层循环,没有异议的超时了,八嘎!
代码:
#include<iostream>
#include<string>
#include<stdio.h>
using namespace std;
int main()
{
int m,n;
int i,j;
while(cin>>m>>n,m,n)
{
for(i=1;i<=n;i++)
{
long long sum=0;
for(j=i;j<=n;j++)
{
sum+=j;
if(sum==n)
{
cout<<'['<<i<<','<<j<<']'<<endl;
break;
}
}
}
cout<<endl;
}
return 0;
}
好吧我承认我水,然后看了大神们的代码,才知道用等差数列公式变形做
Sn=(a1+aN)*n/2
=(a1+a1+d(n-1))*n/2
=a1*n+d(n-1)*n/2;
然后 a1=1,现在又可化简为Sn=n+(n-1)*n/2=(n+1)n/2;
由题意得M=Sn,N为项的个数,则N<=n(max)=sqrt(Sn*2)=sqrt(M*2);
因此原式M=Sn =a1*n+(n-1)n/2=a1*N+(N-1)N/2,可得a1*N=M-(N-1)N/2;
好吧这就可以做了;
代码:
#include <iostream>
#include<cmath>
using namespace std;
int main()
{
int m,n;
while(cin>>m>>n,m,n)
{
int len =(int )sqrt(n*2.0);
int sum=0;
for(;len>0;len--)
{
sum=n-len*(len-1)/2;
if(sum%len==0)
{
cout<<'['<<sum/len<<','<<sum/len+len-1<<']'<<endl;
}
}
cout<<endl;
}
return 0;
}