组合+概率,走一波!!!看懂题意不难,输出格式需要控制一下,注意特殊情况!
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();
}
}