牛客网面试题:年会抽奖(错排算法)

// write your code here

题目描述:

(编程题)今年公司年会的奖品特别给力,但获,奖的规矩却很奇葩:

1.首先,所有人员都将--张写有自己名字的字条放入抽奖箱中;

2.待所有字条加入完毕,每人从箱中取一一个字条;

3.如果抽到的字条上写的就是自己的名字,那么“恭喜你,中奖了!”

现在告诉你参加晚会的人数,请你计算有多少概率会出现无人获奖?

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

输出描述::
对应每组数据 ,以“xx. xx&”的格式输出发生无人获奖的概率。
示例1输入输出示例仅供调试,后台判题数据一般不包含示例

输入
2

输出
50.008

【思路解析】
N个人对应N张纸条,
1如果第一个人有N个选择的机会,那么第二个人就有N-1个选择的机会,第三个人有N-1个选择机会,以此类推,最后一个人只有一个机会。
这其实是排列组合的知识点。
所以:总的可能数=N(N-1)(N-2)...1

2必须错拿:
,如果一个人不能拿自己名字的纸条,那么他可以拿任意剩下的N-1张,
比如,第1个人拿了第k个人的纸条第k个人拿了第1个人的纸条,只需将剩下的N-2个人和N-2个纸条错排。
第1个人拿了第k个人的纸条但是第k个人没有拿第1个人的纸条,只需将N-1个人和N-1个纸条错排。
N个元素的错排总数为F(N)
由递推可得,F(N)=(N-1)[(N-2)+(N-1)]

import java.util.Scanner;
import java.util.Scanner;
public class Main {

   private static float noAward(int n){
        if(n==1){
            return 0;
        }
        if(n==2){
            return  1;
        }else {
            return  (n-1)*(noAward(n-2)+noAward(n-1));
        }
}
 private  static float probability(int n){
   if(n==0||n==1){
       return  1;
   }else {
       return n*probability(n-1);
   }

}
public static void main(String[] args) {
    Scanner scanner=new Scanner(System.in);
    while (scanner.hasNext()){
        int n=scanner.nextInt();
        float noNum=noAward(n);//不可能数

            float sum=probability(n);
       float result=(noNum/sum)*100;

        System.out.println(String.format("%.2f",result)+"%");

    }
}

}

猜你喜欢

转载自blog.51cto.com/14232658/2476046