HDU2058

http://acm.hdu.edu.cn/showproblem.php?pid=2058



The sum problem

Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 10174    Accepted Submission(s): 3111


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]


找一个子序列的和等于M,那么这个子序列可以看成a+1, a+2, ... , a+d 这时,d就为这个序列的长度,起始数字就是a+1,而这个序列的和即M=a*d + (1 + d) * d /2;得出d*d<2 * m,从而可以枚举d,计算出a


#include<iostream>
#include<cmath>

using namespace std;

int main(){
        int n,m;
        int d,b;
        while(cin>>n>>m && (n||m)){
                for(d=sqrt(2.0 *m); d>0;d--){
                        b=m-(d+d*d)/2;
                        if(b%d==0)
                        cout<<"["<<(b/d)+1<<","<<(b/d)+d<<"]"<<endl;
                }
                cout<<endl;
        }
        return 0;
}

网络上的其他相关代码:


#include <stdio.h>
#include <math.h>
int main()
{
	int n, m, len, a;
	while(~scanf("%d%d", &n,&m))
	{
		if(!n && !m)
			break;
		len = sqrt(double(m * 2)) + 1;
		//根据等差数列来算,数列长度
		// m = (a + a + len - 1) * len / 2
		// m = a * len + len(len - 1)/ 2
		// m - len * (len - 1) / 2 = a * len
		//a = m / len - (len - 1) / 2
		while(--len)
		{
			a = m / len - (len - 1) / 2;
			if((a + a + len - 1) * len / 2 == m)
			{
				printf("[%d,%d]\n", a, a+len - 1);
			}
		}
		printf("\n");
	}
	return 0;
}



<think>好的,用户现在想查找关于Java中计算序列求和的解决方案或代码示例。我需要结合之前的对话和提供的引用内容来给出合适的回答。 首先,回顾之前的对话,用户之前询问了如何编写计算阶乘的Java程序,现在转向序列求和。之前的引用中有几个相关的例子,比如递归求和、等差数列求和以及特定数列的求和。需要整合这些信息,提供不同的实现方法,可能包括递归和迭代两种方式。 用户的需求是编写程序实现序列求和,可能需要通用的示例,也可能需要特定的数列类型,比如等差数列或调和数列。根据引用中的例子,例如引用1中的递归求和方法,引用2的等差数列求和,引用3和4中的分数数列求和。因此,我应该展示几种不同的求和方式,让用户了解不同的实现方法。 接下来,需要确定回答的结构。首先介绍常见的序列类型,然后给出每种类型的代码示例。要确保代码符合用户之前的输入验证和结构要求,比如处理输入范围和错误情况。同时,参考之前的回答,可能需要使用递归或迭代,并解释两者的区别和适用场景。 另外,用户可能希望代码示例包括输入处理和输出,像之前的阶乘程序那样。但根据当前问题,用户可能只需要核心的求和部分,或者完整的程序。需要判断这一点,但根据用户提供的示例,可能更倾向于完整的示例,如输入n,计算序列和。 还要注意用户提到的“序列求和”可能包括不同的数列,如算术序列、几何序列、调和序列或其他特定公式的序列。需要覆盖这些情况,或者至少展示几种常见的例子。 最后,根据用户之前的回答,生成相关问题,例如关于递归与迭代的区别、处理大数、或者特定数列的求和方法等。 现在,开始组织内容,分点介绍不同的求和类型,每种类型给出代码示例,并解释关键点。确保使用中文,代码格式正确,结构清晰,参考之前的引用内容,但调整以适应当前的查询。</think>根据需求类型,以下是几种典型的Java序列求和方法实现及代码示例: --- ### 一、基础递归求和(1~n自然数) ```java public class BasicSum { // 递归实现 public static int sumRecursive(int n) { if (n <= 0) return 0; // 输入验证[^1] if (n == 1) return 1; return n + sumRecursive(n - 1); } // 迭代实现 public static int sumIterative(int n) { int sum = 0; for (int i = 1; i <= n; i++) { sum += i; } return sum; } public static void main(String[] args) { System.out.println(sumRecursive(100)); // 输出5050 System.out.println(sumIterative(100)); // 输出5050 } } ``` --- ### 二、等差数列求和 基于引用[2]的代码优化: ```java public class ArithmeticSum { public static int calculate(int n, int firstTerm, int commonDiff) { return n * (2 * firstTerm + (n - 1) * commonDiff) / 2; // 等差数列公式[^2] } public static void main(String[] args) { Scanner scanner = new Scanner(System.in); int n = scanner.nextInt(); System.out.println(calculate(n, 2, 3)); // 示例:首项2,公差3 } } ``` --- ### 三、分数序列求和 参考引用[3][^3]和引用[4][^4]实现: #### 1. 调和数列($\sum_{k=1}^n \frac{k}{k+1}$) ```java public class FractionSum { public static double harmonicSum(int n) { double sum = 0; for (int k = 1; k <= n; k++) { sum += (double)k / (k + 1); // 注意类型转换避免整数除法 } return sum; } public static void main(String[] args) { System.out.printf("%.4f", harmonicSum(5)); // 输出3.5500 } } ``` #### 2. 递归实现分数求和($\sum_{k=1}^n \frac{k}{2k+1}$) ```java public class RecursiveFractionSum { public static double sum(int n) { if (n <= 0) return 0; return (double)n / (2 * n + 1) + sum(n - 1); } public static void main(String[] args) { System.out.printf("%.2f", sum(10)); // 输出4.41 } } ``` --- ### 四、通用序列求和框架 ```java import java.util.function.DoubleUnaryOperator; public class GenericSeries { public static double calculate(int n, DoubleUnaryOperator formula) { double sum = 0; for (int k = 1; k <= n; k++) { sum += formula.applyAsDouble(k); } return sum; } public static void main(String[] args) { // 示例1:计算∑k^2 double squareSum = calculate(5, k -> k * k); // 1+4+9+16+25=55 System.out.println(squareSum); // 示例2:计算∑1/(k^3) double cubeReciprocal = calculate(3, k -> 1/(k*k*k)); // 1 + 1/8 + 1/27≈1.162 System.out.printf("%.3f", cubeReciprocal); } } ``` --- ### 关键实现要点 1. **输入验证**:对所有用户输入进行范围检查(如n≥1) 2. **数值精度**:使用`double`类型处理分数,注意避免整数除法 3. **算法选择**: - 递归适合数学关系明确的场景(如斐波那契数列) - 迭代更适用于大规模计算(避免栈溢出风险) 4. **公式抽象**:通过函数式接口实现通用计算框架 ---
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值