第十届蓝桥杯 JavaA 组合数问题

第十届蓝桥杯 JavaA 组合数问题


在这里插入图片描述
在这里插入图片描述


法一:
思路:
通过定义计算组合数,再取余
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;

/**
 * 法1:通过定义计算组合数,再取余
 * 
 * @description TODO
 * @author frontier
 * @time 2019年4月9日 下午8:30:51
 *
 */
public class J组合数问题1 {
	static Scanner in = new Scanner(System.in);
	static int t;
	static long n, m, k;
	static int count;

	public static void main(String[] args) throws FileNotFoundException {
		long time = System.currentTimeMillis();
		Scanner in = new Scanner(new File("src/JavaA/s10/10.txt"));
		t = in.nextInt();
		k = in.nextInt();
		while (t-- != 0) {
			n = in.nextInt();
			m = in.nextInt();
			count = 0;
			for (long i = 1; i <= n; ++i) {
				long min = Math.min(i, m);
				for (int j = 0; j <= min; ++j) {

					long temp = 1;
					for (long p = 1; p <= i; ++p)
						temp *= p;
					for (long p = 1; p <= j; ++p)
						temp /= p;
					for (long p = 1; p <= i - j; ++p)
						temp /= p;

					if (temp % k == 0) {
						count++;
						count %= 1e9 + 7;
					}
				}
			}
			System.out.println(count);
		}
		System.out.println((System.currentTimeMillis() - time) + "ms");
	}
}

法二(最常用):
思路:
通过地推公式计算,记录已计算的c(n,m)
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;

/**
 * 法2:通过地推公式计算,记录已计算的c(n,m)
 * 
 * @description TODO
 * @author frontier
 * @time 2019年4月9日 下午8:34:11
 *
 */
public class J组合数问题2 {
	static Scanner in = new Scanner(System.in);
	static int t;
	static long n, m, k;
	static int count;
	static long[][] c = new long[2005][2005];

	public static void main(String[] args) throws FileNotFoundException {
		long time = System.currentTimeMillis();
		Scanner in = new Scanner(new File("src/JavaA/s10/10.txt"));
		t = in.nextInt();
		k = in.nextInt();
		while (t-- != 0) {
			n = in.nextInt();
			m = in.nextInt();
			count = 0;
			for (int i = 1; i <= n; ++i) {
				long min = Math.min(i, m);
				for (int j = 0; j <= min; ++j) {

					if (c(i, j) == 0) {
						count++;
						count %= 1e9 + 7;
					}
				}
			}
			System.out.println(count);
		}
		System.out.println((System.currentTimeMillis() - time) + "ms");
	}

	static long c(int n, int m) {
		if (m == 0 || m == n)
			return 1;
		if (c[n][m] != 0)
			return c[n][m];
		return c[n][m] = (c(n - 1, m - 1) + c(n - 1, m)) % k;
	}
}

法三:
思路:
通过定义式的变形来计算
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;

/**
 * 法3:通过定义式的变形来计算
 * 
 * @description TODO
 * @author frontier
 * @time 2019年4月9日 下午8:34:11
 *
 */
public class J组合数问题3 {
	static Scanner in = new Scanner(System.in);
	static int t;
	static long n, m, k;
	static int count;
	static long[][] c = new long[2005][2005];

	public static void main(String[] args) throws FileNotFoundException {
		long time = System.currentTimeMillis();
		Scanner in = new Scanner(new File("src/JavaA/s10/10.txt"));
		t = in.nextInt();
		k = in.nextInt();
		while (t-- != 0) {
			n = in.nextInt();
			m = in.nextInt();
			count = 0;
			for (int i = 1; i <= n; ++i) {
				long min = Math.min(i, m);
				for (int j = 0; j <= min; ++j) {

					if (c(i, j) % k == 0) {
						count++;
						count %= 1e9 + 7;
					}
				}
			}
			System.out.println(count);
		}
		System.out.println((System.currentTimeMillis() - time) + "ms");
	}

	static long c(int n, int m) {
		long temp = 1;
		for (int i = 1; i <= m; ++i)
			temp = temp * (n - m + i) / i;
		return temp;
	}
}

法三:
思路:
lucas。前几种本题都不能得全分。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值