首页 > 试题广场 >

年会抽奖

[编程题]年会抽奖
  • 热度指数:5118 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32M,其他语言64M
  • 算法知识视频讲解
今年公司年会的奖品特别给力,但获奖的规矩却很奇葩:
1. 首先,所有人员都将一张写有自己名字的字条放入抽奖箱中;
2. 待所有字条加入完毕,每人从箱中取一个字条;
3. 如果抽到的字条上写的就是自己的名字,那么“恭喜你,中奖了!”
现在告诉你参加晚会的人数,请你计算有多少概率会出现无人获奖?

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


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

输入

2

输出

50.00%

// write your code here
import java.util.Scanner;


public class Main {
    public static void main(String[] args) {

        Scanner scanner = new Scanner(System.in);
        while (scanner.hasNextInt()) {
            int n = scanner.nextInt();
            if(n==0||n==1){
                System.out.println("00.00%");
                continue;
            }
            long[] D = new long[n + 1];
            D[1] = 0;
            D[2] = 1;
            //n>=2 不越界
            for (int i = 3; i <= n; i++) {
                D[i] = (i - 1) * (D[i - 1] + D[i - 2]);
            }
            long total = 1;
            for (int i = 2; i <= n; i++) {
                total *= i;
            }
            System.out.printf("%.2f", D[n] * 1.0 / total * 100);
            System.out.println("%");
        }
    }
}


发表于 2022-09-14 22:28:37 回复(0)
import java.util.*;
public class Main{
    public static long notSelf(int n){
        long[] arr = new long[21];
        arr[0] = 0;
        arr[1] = 0;
        arr[2] = 1;
        for(int i = 3;i < arr.length;i++){
            arr[i] = (i - 1) * (arr[i - 1] + arr[i - 2]);
        }
        return arr[n];
    }
    public static float fun(int n){
        if(n == 0){
            return 1;
        }
        float res = 1;
        for(int i = 1;i <= n;i++){
            res *= i;
        }
        return res;
    }
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        while(sc.hasNext()){
            int n = sc.nextInt();
            float s = (float)notSelf(n)/fun(n);
            System.out.printf("%2.2f%%\n",s*100);
        }
    }
}

编辑于 2022-05-19 15:41:45 回复(0)
答案来自牛客网账号:南山北~~
import java.util.*;

public class Main {
	public static void main(String[] args) {
		// 输入
		Scanner scan = new Scanner(System.in);
		while(scan.hasNext()){
			int n = scan.nextInt(); // 代表测试数据的组数
			float sum1 = factorial(n);
			float sum2 = count(n);
            //将得到的分子分母进行相除,就可以得到概率了。
            float result1 = (sum2/sum1)*100;
            System.out.println(String.format("%.2f", result1) + "%");
		}
		
	}
	/**
	 * 错排算法
	 * @param n
	 * @return
	 */
	public static float count(int n) {
		if(n==1){
			return 0;
		}else if(n==2){
			return 1;
		}else{
			return (n-1)*(count(n-1)+count(n-2));
		}
		
	}
	/**
	 * n的阶乘
	 * @param num
	 * @return
	 */
	 public static float factorial(int num) {
	        float result = 1;
	        if(num==0){
	        	return 1;
	        }else if (num > 0) {
	            result = num * factorial(num - 1);
	        }
	        return result;
	    }

}

发表于 2016-08-26 15:05:18 回复(0)
import java.util.Scanner;
//代码已通过测试,还望各位牛友批评指正
public class Main{
    //这道题着实让我折腾了好半天,首先要明白这是一个排列组合问题,
    //我们拿5来说事,首先5个人来进行抽奖,有多少种抽法?
    //因为是不放回抽,所以第一个人有5种抽法,
    //第二个人有4种抽法,依次类推
    //总共就是5! 对有5的阶乘种抽法。这是分母
    //那可想而知分子就是存在多少种情况每个人拿不到自己的名字。
    //这里要应用错排算法。
    //简单的做个介绍
    //当n个编号元素放在n个编号位置,元素编号与位置编号各不对应的方法数用D(n)表示,
    //那么D(n-1)就表示n-1个编号元素放在n-1个编号位置,各不对应的方法数,其它类推.
    //第一步,把第n个元素放在一个位置,比如位置k,一共有n-1种方法;
    //第二步,放编号为k的元素,这时有两种情况:把它放到位置n,那么,对于剩下的n-1个元素,
    //由于第k个元素放到了位置n,剩下n-2个元素就有D(n-2)种方法;
    //第k个元素不把它放到位置n,这时,对于这n-1个元素,有D(n-1)种方法;
    //综上得到递推公式,可以发现可以用递归来做;
    //D(n) = (n-1) [D(n-2) + D(n-1)]
    //特殊地,D(1) = 0, D(2) = 1.
    //那么D(5)=4*[D(3)+D(4)];依次求得D(3)、D(4),最后D(5)=44
    //所以5个人拿不到奖的概率就是44/120=36.67%
    //这里只是简单介绍,具体想弄明白还是去百度错排算法吧
    //下面看代码
    public static float count(int n) {
        //这个函数用来得到有多少种可能,每个人拿不到自己的名字,
        //也就是得到分子
        if(n==1){
            //n=1的时候返回0
            return 0;
        }
        if(n==2){
            //n=2的时候返回1
            return 1;
        }else{
            //否则就递归。
            return (n-1)*(count(n-1)+count(n-2));
        }
    }
    //下面的函数用来求阶乘,也是递归,最后得到分母
    public static float probability(int n){
       if(n==0){
           //0的阶乘等于1,不用多说吧
           return 1;
       }else{
           //阶乘表示,进行递归
           return n*probability(n-1);
       }
    }
    
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        do {
            int n = sc.nextInt();
            //将得到的分子分母进行相除,就可以得到概率了。
            float result = (count(n)/probability(n))*100;
            System.out.println(String.format("%.2f", result) + "%");
        } while (sc.hasNext());
    }
}

编辑于 2016-08-25 17:06:21 回复(0)

问题信息

难度:
4条回答 15934浏览

热门推荐

通过挑战的用户