codeforces 107B(Basketball Team) 组合+概率 Java

组合+概率,走一波!!!看懂题意不难,输出格式需要控制一下,注意特殊情况!

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.math.BigDecimal;
import java.text.NumberFormat;
import java.util.Scanner;

/**
 * 题意:一个团队需要 n 个人,学校有 m 个系(编号:1-m),主人公在 h 系; 
 *      第二行输入 s[i] 表示第 i 系的人数(包括主人公自己)。
 *      在所有系中随机挑选 n 个人,问跳出的人中存在和主人公所在同一系的概率。
 * 
 * C(下标,上标)、sum 表示全校人数 
 * 分析:P(团队中没有人和主人公在同一个系) = (在全校总人数-h系人数中选出n-1人)/(在全校人数-1中选择n-1人) 
 * 即:C(sum-s[h],n-1)/C(sum-1,n-1) = A(s-s[h],n-1)/A(s-1,n-1) 
 * 结果 = 1 - p(不在同一个系) = 1 - A(s-s[h],n-1)/A(s-1,n-1);
 * 
 * @author TinyDolphin
 *
 */
public class Main {

    public static void main(String[] args) {
        Scanner in = new Scanner(new BufferedReader(new InputStreamReader(System.in)));
        PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
        int teamNum; // 团队所需人数
        int departmentNum; // 系的数量
        int currentDepart; // 主人公所在系编号
        int studentSum; // 学校总人数
        int currentDepartNum; // 主人公所在系的人数
        while (in.hasNext()) {
            teamNum = in.nextInt();
            departmentNum = in.nextInt();
            currentDepart = in.nextInt();
            currentDepartNum = 0;
            studentSum = 0;
            int temp;
            // 记录主人公所在系的人数以及全校总人数
            for (int index = 1; index <= departmentNum; index++) {
                temp = in.nextInt();
                studentSum += temp;
                if (index == currentDepart) {
                    currentDepartNum = temp;
                }
            }
            if (studentSum < teamNum) {
                out.println(-1);
            } else if (teamNum == 1) {
                out.println(0);
            } else {
                // 计算 A(s-s[h],n-1)/A(s-1,n-1)
                BigDecimal denominator = BigDecimal.valueOf(studentSum - 1); // 分母
                BigDecimal member = BigDecimal.valueOf(studentSum - currentDepartNum); // 分子
                BigDecimal tempBD1 = denominator;
                BigDecimal tempBD2 = member;
                while (teamNum-- > 2) {
                    tempBD1 = tempBD1.subtract(BigDecimal.valueOf(1));
                    denominator = denominator.multiply(tempBD1);
                    tempBD2 = tempBD2.subtract(BigDecimal.valueOf(1));
                    member = member.multiply(tempBD2);
                }
                // 注意此处:大浮点数相除,除不断时,会报异常。所以需要设置结果长度以及四舍五入的方法
                double ans = 1 - member.divide(denominator, 6, BigDecimal.ROUND_HALF_UP).doubleValue();
                NumberFormat numberFormat = NumberFormat.getInstance();
                // 设置数值的小数部分允许的最大位数
                numberFormat.setMaximumFractionDigits(6);
                // 去掉小数后面多余的零
                out.println(numberFormat.format(ans));
            }
        }
        out.flush();
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值