编程题:年会抽奖(错排算法)


链接: 年会抽奖
来源:牛客网

问题描述:

在这里插入图片描述

解题思路:

解这个题的时候,我们应该先明白:什么时候算都不获奖?全部不获奖的概率又该怎么计算?

全部不获奖的概率=N个人都拿错的情况/所有人的排列情况数
而所有人的排列情况数=N!(第一个人有N种情况,第二个有N-1种,直到最后一个人)

N个人都拿错的情况和这个题:发邮件 的情况是一样的。

假设a的名字没有被a拿到,除他之外的N-1个人都有可能拿到,即有N-1种情况。 假设b这个时候拿到了a的名字,那么对于b的名字有两种情况:
  第一种:b的名字是被a拿到了,也就是a和b互相拿到了对方的名字,那么对于其他的N-1个人来说互相拿错又是一个子问题f(n-2) ;
  第二种:b的名字没有被a拿到,则剩下的问题是子问题 f(n-1).
  
因此:可以得出递推公式:f(n)=(n-1)*(f(n-1)+f(n-2))   

解题代码:

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc=new Scanner(System.in);
        while(sc.hasNext()){
             int n=sc.nextInt();
             double sum1=factorial(n);
             double sum2=count(n);
             double result=(sum2/sum1)*100; //计算成%的形式
            System.out.println(String.format("%.2f",result)+"%");
        }
    }
    //计算所有人都抽不到奖的情况:错排算法
    private static double count(int n) {
      if(n==1){
          return 0;
      }else if(n==2){
          return 1;
      }else {
          return (n-1)*(count(n-1)+count(n-2));
      }
    }

    //计算阶乘:迭代写法
    private static double factorial(int n) {
        double sum=1;
        while(n>1){
           sum=sum*n;
           n--;
        }
        return sum;
    }
    //计算阶乘:递归写法
    private  static double factorical2(int n){
       if(n==0||n==1){
           return 1;
       }
       return n*factorical2(n-1);
    }
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值