我和计算机一起完成全国卷的第5题

博主分享了如何使用编程解决2022年全国Ⅰ卷的一道数学题,通过编写Java代码实现自动化求解,并展示了部分测试效果。虽然当前结果未进行分式化简,但计划后续会加入约简算法。鼓励读者关注并支持。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在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;
        }
    }
}

这里是几个测试的效果

 

 为了让显示的结果是否符合预期,所以这里暂时就没有将最终结果进行化简,后期会实现分式的约简算法

关注我,给博主点个赞吧

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值