在2022年全国Ⅰ卷中,有这样一道题,
我在想,如果能带上计算机,提前准备好了程序,那么什么大神,又或是妖魔鬼怪都不及我跑一个代码来得轻松。
下面是解决这个问题的代码。
package util;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Scanner;
public class Combination {
public static void main(String... args){
String control = "Y"; // 控制循环的结束与继续
Combination combination = new Combination();
Scanner scan = new Scanner(System.in);
do {
System.out.println("请输入第一个整数");
int start = scan.nextInt();
System.out.println("请输入第二个整数");
int end = scan.nextInt();
System.out.println("输出形式结果,请输入F/f,输出小数结果,请输入D/d");
String judge = scan.next();
if (judge.equals("F") || judge.equals("f")){
System.out.print("得到的概率为:");
System.out.println(combination.getPrimPro(start, end, false));
}else if (judge.equals("D") || judge.equals("d")) {
System.out.print("得到的概率为:");
System.out.println(combination.getPrimPro(start, end, true));
}
System.out.println("如果要继续,则输入Y/y,否则输入其它");
control = scan.next();
}while (control.equals("Y") || control.equals("y"));
}
/**
* 求抽取两数为质数的概率
* @param start 一串连续整数的起始位置
* @param end 一串连续整数的终止位置
* @param judge 判断返回结果是小数表达还是准确形式表达,如果为true则是小数表达
* @return 返回用小数表达的概率值,或者准确形式表达的概率值
*/
public String getPrimPro(int start, int end, boolean judge) {
BigDecimal[] bigDecimals = this.getPrimPro(start, end);
if (judge == true) {
BigDecimal bigDecimalNumerator = new BigDecimal(bigDecimals[0]+".00");
return "" + bigDecimalNumerator.divide(bigDecimals[1], BigDecimal.ROUND_HALF_EVEN);
}else {
return "" + bigDecimals[0] + "/" + bigDecimals[1];
}
}
/**
* 求抽取两数为质数的概率
* @param start 一串连续整数的起始位置
* @param end 一串连续整数的终止位置
* @return 返回概率的分子分母
*/
private BigDecimal[] getPrimPro(int start, int end) {
// 先对用户输入的数据是否正确进行检查
try {
if (start >= end || start < 0) {
System.out.println("抱歉,您输入的第一个参数的值应当比第二个参数的值大");
return null;
}
int[] array = new int[end-start+1];
}catch (Exception e) {
System.out.println("获取你输入了不正确的参数");
e.printStackTrace();
}
// 计算总的可能性 C_{end}^{2}=end!/(2!(end-2)!)
int numeratorN = this.n(end-start+1);
//int denominatorN2 = this.n(2);
int denominatorN = this.n(end-start-1);
BigDecimal bigDecimalNumerator = new BigDecimal(""+numeratorN);
BigDecimal bigDecimalDenominator2 = new BigDecimal("2");
BigDecimal bigDecimalDenominatorN = new BigDecimal(""+denominatorN);
// 算得总的可能数
BigDecimal bigDecimalSum = bigDecimalNumerator.divide(bigDecimalDenominator2.multiply(bigDecimalDenominatorN));
// 这里计算质数的组合数
int sumPrim = 0;
for (int i = start; i < end; i++){
int step = 1;
while (step < i){
if (this.isPrim(i, step)){
sumPrim = sumPrim + (end - step) / i;
//System.out.println(sumPrim);
}else if (step == 1){
sumPrim = sumPrim + (end - step) / i;
//System.out.println(sumPrim);
}
step++;
}
}
return new BigDecimal[]{new BigDecimal(""+sumPrim), bigDecimalSum};
}
/**
* 阶乘
*/
public int n(int n){
int pro = 1;
for (int i = 1; i <= n; i++) {
pro *= i;
}
return pro;
}
/**
* 判断两数是否互质
* @return boolean 如果为true,则表示两数互质,否则表示具有公因数
*/
public boolean isPrim(int a, int b){
if(a > b){
int change = b;
b = a;
a = change;
}
if(a==1 || b==1)
return true;
else {
while(true) {
int temp = a % b;
if(temp ==0) {
break;
}else {
a = b;
b = temp;
}
}
if(b == 1) //最大公约数为1,所以互质
return true;
else //最大公约数大于1,所以不互质
return false;
}
}
}
这里是几个测试的效果
为了让显示的结果是否符合预期,所以这里暂时就没有将最终结果进行化简,后期会实现分式的约简算法
关注我,给博主点个赞吧