HDU 2058 - The sum problem(等差數列)
The sum problem
Time Limit: 5000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 30916 Accepted Submission(s): 9249
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 3
0 0 0
Sample Output
[1,4]
[10,10]
[4,8]
[6,9]
[9,11]
[30,30]
題意:
給你從1到N個數,使他的連續子序列和為m,求連續子序列的範圍。
思路:
暴力肯定是不行的,後來想到他是等差數列,公差是1,前n項和為m。
利用等差數列的求和公式Sn = n*a1 + n*(n-1)/2,帶入公差、前n項和得m=a1*n+n*(n-1)/2。
假設首項是1,我們代入m=a1*n+n*(n-1)/2,則有n(n+1)=2m。
所以有n*(n+1)=2m>n*n,即n<sqrt(2m); 也就是說項數最多的情況也只有sqrt(2m)。
首項a1=(m*2/i-i+1)/2 。
然後列舉等差數列的長度就行了。
程式碼:
#include<stdio.h>
#include<math.h>
int main()
{
int n,m,i,a1,k;
while(scanf("%d%d",&n,&m)!=EOF)
{
if(n==0&&m==0)
break;
k=sqrt((double)(m)*2);
for(i=k;i>0;i--)
{
a1=(m*2/i-i+1)/2;
if((i*a1+i*(i-1)/2)==m)
{
if(a1>0)
printf("[%d,%d]\n",a1,a1+i-1);
}
}
printf("\n");
}
return 0;
}