第十届蓝桥杯 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。前几种本题都不能得全分。