《年会抽奖》:无人获奖的概率

目录

一、题目 

二、思路

1、错排问题

 2、n 的阶乘

3、输出格式要求

三、代码


 

一、题目 

题目:年会抽奖            题目链接:年会抽奖

        今年公司年会的奖品特别给力,但获奖的规矩却很奇葩:
1. 首先,所有人员都将一张写有自己名字的字条放入抽奖箱中;
2. 待所有字条加入完毕,每人从箱中取一个字条;
3. 如果抽到的字条上写的就是自己的名字,那么“恭喜你,中奖了!”
        现在告诉你参加晚会的人数,请你计算有多少概率会出现无人获奖?

输入描述:
        输入包含多组数据,每组数据包含一个正整数n(2≤n≤20)。

输出描述:
        对应每一组数据,以“xx.xx%”的格式输出发生无人获奖的概率。
输入
2
输出
50.00%

二、思路

        需要计算没有人获奖的概率,则需要两个数值,一个是没有人获奖的情况的数量(错排问题),一个是所有的情况(排列组合)的数量。

1、错排问题

        用A、B、C……表示写着n位友人名字的信封,a、b、c……表示n份相应的写好的信纸。把错装的总数为记作D(n)。假设把a错装进B里了,包含着这个错误的一切错装法分两类:

  • b装入A里,这时每种错装的其余部分都与A、B、a、b无关,应有D(n-2)种错装法。
  • b装入A、B之外的一个信封,这时的装信工作实际是把(除a之外的)n-1份信纸b、c……装入(除B以外的)n-1个信封A、C……,显然这时装错的方法有D(n-1)种。

总之在a装入B的错误之下,共有错装法D(n-2)+D(n-1)种。

a装入C,装入D……的n-2种错误之下,同样都有D(n-1)+D(n-2)种错装法。因此D(n)=(n-1)[D(n-1)+D(n-2)]

D(n) = (n-1) [D(n-2) + D(n-1)]
特殊地,D(1) = 0、 D(2) = 1

 公式推导: 《年会抽奖》:无人获奖的概率_第1张图片

 2、n 的阶乘

        分母是所有抽奖的情况,即所有总数的排列组合,即 n的阶乘。利用数组,每次进行累乘即可。

3、输出格式要求

        要使用“xx.xx%”的格式输出,因此我们使用 printf格式化输出。

%f:输出小数点类型

%.2f:指定输出小数点后两位。

        输出中还要有 %,因此要使用 %% 来输出 %。 

三、代码

import java.util.Scanner;
/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: WangWZ
 * Date: 2023-04-14
 * Time: 13:39
 */
public class Main {
    public static void main(String[] args) {
        //arr存放错装数
        //注意有20个数,但是我们数组里的0是不用的
        //因此要创建一个21个元素的数组
        long[] arr = new long[21];
        arr[0] = 0;
        arr[1] = 0;
        arr[2] = 1;
        //sum 存放总的排列组合个数
        long[] sum = new long[21];
        sum[0] = 0;
        sum[1] = 1;
        sum[2] = 2;
        for (int i = 3; i <= 20; i++) {
            arr[i] = (i - 1) * (arr[i - 1] + arr[i - 2]);
            sum[i] = i * sum[i - 1];
        }
        Scanner sc = new Scanner(System.in);
        while(sc.hasNextInt()) {
            int n = sc.nextInt();
            System.out.printf("%.2f%%\n",100.0*arr[n]/sum[n]);
        }
    }
}

你可能感兴趣的:(题目练习,算法,java,数据结构)