自述:
这道题我没能解决,原题直接运行错误,应该是哪个地方少考虑了,希望以后能过优化通过这题吧。
题目描述:
输入n, m, k,输出下面公式的值。
其中C_n^m是组合数,表示在n个人的集合中选出m个人组成一个集合的方案数。组合数的计算公式如下:
数据规模和约定
对于100%的数据,n在十进制下不超过1000位,即1≤n< 10^1000,1≤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;
}
}