公式求值-Java

自述:

这道题我没能解决,原题直接运行错误,应该是哪个地方少考虑了,希望以后能过优化通过这题吧。

题目描述:

输入n,  m,  k,输出下面公式的值。

在这里插入图片描述

其中C_n^m是组合数,表示在n个人的集合中选出m个人组成一个集合的方案数。组合数的计算公式如下:

在这里插入图片描述

数据规模和约定 
对于100%的数据,n在十进制下不超过1000位,即1≤n< 10^10001≤k≤1000,同时0≤m≤n,k≤n。 
提示 
999101是一个质数; 
当n位数比较多时,绝大多数情况下答案都是0,但评测的时候会选取一些答案不是0的数据; 

输入:

输入的第一行包含一个整数n;第二行包含一个整数m,第三行包含一个整数k。

输出:

计算上面公式的值,由于答案非常大,请输出这个值除以999101的余数。 

样例输入:

3 
1 
3 

样例输出:

162

参考解答:

import java.util.Scanner;

public class Main {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		String n = sc.nextLine();
		String m = sc.nextLine();
		int k = sc.nextInt();
		System.out.println(sum(n, m, k));
	}
	
	private static String sum(String n, String m, int k) {
		String result = "0";
		String combinatorial_number_n_m = combinatorial_number(n, m);
		System.out.println("in");
		for (String i = "0"; !isBigger(i, n); i = plus(i, "1")) {
			result = plus(result, multiply(multiply(combinatorial_number(n, i), combinatorial_number_n_m), power(i, k)));
			System.out.println(i);
		}
		System.out.println("out");
		return modulo(result, "999101");
	}
	
	private static String combinatorial_number(String n, String m) {
		return divide(factorial(n), multiply(factorial(m), factorial(minus(n, m))));
	}
	
	private static String factorial(String n) {
		String result = "1";
		while (n != "1" && n != "0") {
			result = multiply(result, n);
			n = minus(n, "1");
		}
		return result;
	}
	
	private static String plus(String a, String b) {
		String result = null;
		if (a.length() < b.length()) {
			String temp = a;
			a = b;
			b = temp;
		}
		char[] arr_max = a.toCharArray();
		char[] arr_min = b.toCharArray();
		int carry = 0;
		int length_max = arr_max.length;
		int length_min = arr_min.length;
		for (int i = 1; i <= length_max; i++) {
			int char_a = arr_max[length_max - i] - '0';
			int char_b;
			if (length_min - i >= 0) {
				char_b = arr_min[length_min - i] - '0';
			}
			else {
				char_b = 0;
			}
			int temp_sum = char_a + char_b + carry;
			carry = temp_sum / 10;
			arr_max[length_max - i] = (char) (temp_sum % 10 + '0');
		}
		if (carry != 0) {
			result = (char)(carry + '0') + new String(arr_max);
		}
		else {
 			result = new String(arr_max);
		}
		return result;
	}
	
	private static String minus(String a, String b) {
		if (a.equals(b)) {
			return "0";
		}	
		String result = a;
		char[] arr_min = b.toCharArray();
		int length_result = result.length();
		int length_min = arr_min.length;
		for (int i = 1; i <= length_min; i++) {
			char[] arr_result = result.toCharArray();

			int char_a = arr_result[length_result - i] - '0';
			int char_b = arr_min[length_min - i] - '0';
			int borrow = 0;
			if (char_b > char_a) {
				for (int j = 1; j <= length_result - i; j++) {
					if (arr_result[length_result - i - j] == '0') {
						arr_result[length_result - i - j] = '9';
					}
					else {
						arr_result[length_result - i - j] -= 1;
						break;
					}
				}
				borrow = 10;
			}
			int temp_sum = char_a - char_b + borrow;
			arr_result[length_result - i] = (char) (temp_sum % 10 + '0');
			result = new String(arr_result);
		}
		return remove_prefix_zero(result);
	}
	
	private static String multiply(String a, String b) {
		if (a.equals("0") || b.equals("0")) {
			return "0";
		}
		String result = "0";
		if (a.length() < b.length()) {
			String temp = a;
			a = b;
			b = temp;
		}
		
		char[] arr_min = b.toCharArray();		
		int length_min = arr_min.length;
		String ten_power = "";
		for (int i = 1; i <= length_min; i++) {
			String temp_result = "0";
			int carry = 0;
			char[] arr_max = a.toCharArray();
			int length_max = arr_max.length;
			int char_b = arr_min[length_min - i] - '0';
			for (int j = 1; j <= length_max; j++) {
				int char_a = arr_max[length_max - j] - '0';
				int temp_product = char_a * char_b + carry;
				carry = temp_product / 10;
				arr_max[length_max - j] = (char) (temp_product % 10 + '0');
			}
			if (carry != 0) {
				temp_result = (char)(carry + '0') + new String(arr_max);
			}
			else {
				temp_result = new String(arr_max);
			}
			temp_result += ten_power;
			ten_power += "0";
			result = plus(result, temp_result);
		}
		return result;
	}
	
	private static String divide(String a, String b) {
		if (b.equals("1")) {
			return a;
		}
		else if(a.equals("0") || isBigger(b, a)) {
			return "0";
		}
		int length_max = a.length();
		char[] arr_max = a.toCharArray();
		String result = "";	
		String dividend = "";
		for (int i = 0; i < length_max; i++) {
			dividend += arr_max[i];
			for (int j = 0; j <= 9; j++) {
				String multiple = "" + (char) (j + '0');
				if (multiply(b, multiple).equals(dividend) || isBigger(plus(multiply(b, multiple), b), dividend)) {
					String difference = minus(dividend, multiply(b, multiple));
					dividend = difference;
					result += multiple;
					break;
				}
			}
		}
		return remove_prefix_zero(result);
	}
	
	private static String power(String a, int k) {
		String result = "1";
		for (int i = 0; i < k; i++) {
			result = multiply(result, a);
		}
		return result;
	}
	
	private static String modulo(String a, String b) {
		while (isBigger(a, b)) {
			a = minus(a, b);
		}
		return a;
	}
	
	private static boolean isBigger(String a, String b) {
		if (a.length() > b.length()) {
			return true;
		}
		else if (a.length() < b.length()) {
			return false;
		}
		else {
			for (int i = 0; i < a.length(); i++) {
				if (a.charAt(i) == b.charAt(i)) {
					continue;
				}
				else {
					return a.charAt(i) > b.charAt(i);
				}
			}
			return false;
		}
	}
	
	private static String remove_prefix_zero(String result){
		if (!result.equals("0") && result.charAt(0) == '0') {
			int new_index;
			for (new_index = 0; new_index < result.length(); new_index++) {
				if (result.charAt(new_index) != '0') {
					break;
				}
			}
			result = result.substring(new_index);
		}
		return result;
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
好的,关于求π的并行实现,我可以提供以下思路: 1. 划分任务:将π的计算任务划分为多个子任务,每个子任务计算一部分π的。 2. 分配任务:将子任务分配给不同的线程或进程并发执行。 3. 同步结果:等待所有线程或进程执行完毕后,将它们计算出的π的合并起来得到最终结果。 以下是一种基于Java的并行实现: ``` import java.util.concurrent.*; public class ParallelPi { public static void main(String[] args) throws InterruptedException, ExecutionException { int numThreads = 4; // 设定线程数 int numSteps = 100000000; // 计算π的步数 double step = 1.0 / numSteps; // 步长 ExecutorService executor = Executors.newFixedThreadPool(numThreads); // 创建线程池 Future<Double>[] futures = new Future[numThreads]; // 创建Future数组 for (int i = 0; i < numThreads; i++) { int start = i * numSteps / numThreads; int end = (i + 1) * numSteps / numThreads; Callable<Double> task = new PiCalculator(start, end, step); // 创建任务 futures[i] = executor.submit(task); // 提交任务 } double sum = 0.0; for (int i = 0; i < numThreads; i++) { sum += futures[i].get(); // 合并结果 } double pi = step * sum * 4.0; System.out.println("π ≈ " + pi); executor.shutdown(); // 关闭线程池 } } class PiCalculator implements Callable<Double> { private final int start; private final int end; private final double step; public PiCalculator(int start, int end, double step) { this.start = start; this.end = end; this.step = step; } @Override public Double call() throws Exception { double sum = 0.0; for (int i = start; i < end; i++) { double x = (i + 0.5) * step; sum += 1.0 / (1.0 + x * x); } return sum; } } ``` 以上代码中,我们使用了Java的Executor框架,将π的计算任务划分为多个子任务,并发执行,最后将结果合并得到最终的π。此外,为了提高计算精度,我们使用了莱布尼茨级数公式计算π的
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值