设为首页 加入收藏

TOP

HDU 2058 The sum problem
2014-11-23 21:42:16 来源: 作者: 【 】 浏览:5
Tags: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): 12104 Accepted Submission(s): 3666


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]
总结:

观察a+1,a+2…a+d
全部相加等于M
即(a+1+a+d)*d/2 = M,
这里d是平方,我们可以从长度d入手,这样就能把范围由M转换成M^1/2 ;


这里把代码中的①和②解释下:
①:当a+1,a+2…a+3相加等于M时,即
(a+1+a+d)*d/2 = M
而a最小是0,所以(d+1)*d/2=M时d去最大值,就是这步把时间复杂度减小的。
d就是sqrt(2*M)

②:(a+1+a+d)*d/2 = M
所以a*d + (d+1)/2 = M
所以要使等式成立,M-(d+1)/2必须是d的倍数。


import java.util.*;
import java.io.*;
import java.math.BigInteger;
public class Main {
	public static void main(String[] args) {
		Scanner sc=new Scanner(new BufferedInputStream(System.in));
		while(sc.hasNextInt()){ 
			int n=sc.nextInt();
			int m=sc.nextInt();
			if(n==0&&m==0)
				System.exit(0);
			int t1=(int)Math.sqrt(2*m);
			for(int i=t1;i>=1;i--){
				long temp=m-(i*i+i)/2;
				if(temp%i==0)
					System.out.println("["+(temp/i+1)+","+(temp/i+i)+"]");
			}
			System.out.println();
		}
		
	}
	
}

】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇九度笔记之 1342:寻找最长合法括.. 下一篇HDU 3333 树状数组+离线处理

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容:

·Redis on AWS:Elast (2025-12-27 04:19:30)
·在 Spring Boot 项目 (2025-12-27 04:19:27)
·使用华为开发者空间 (2025-12-27 04:19:24)
·Getting Started wit (2025-12-27 03:49:24)
·Ubuntu 上最好用的中 (2025-12-27 03:49:20)