概率

1足球比赛

有2k只球队,有k-1个强队,其余都是弱队,随机把它们分成k组比赛,每组两个队,问两强相遇的概率是多大?

给定一个数k,请返回一个数组,其中有两个元素,分别为最终结果的分子和分母,请化成最简分数

测试样例:
4
返回:[3,7]
import java.util.*;
  
public class Championship {
    public int[] calc(int k) {
        // write code here
          
        int A=1;
        int B=1;
          
        //求总的组合数
        for(int i=2*k-1;i>0;i-=2){
            A*=i;
        }
          
        //强队不相遇数目(C(k+1,k-1))
        for(int i=3;i<=k+1;i++){
            B*=i;
        }
          
        
          
        //for(int i=k-1;i>0;i--){
       //     B/=i;
      //  }
          
        int gcd=gcd(A,B);
          
        A=A/gcd;
        B=B/gcd;
          
        int[]res=new int[2];
        res[0]=A-B;
        res[1]=A;
          
        return res;
          
          
    }
      
    public int gcd(int a,int b){
        while(b>0){
            int t=b;
            b=a%b;
            a=t;
              
        }
          
        return a;
    }
}

2蚂蚁

n只蚂蚁从正n边形的n个定点沿着边移动,速度是相同的,问它们碰头的概率是多少?

给定一个正整数n,请返回一个数组,其中两个元素分别为结果的分子和分母,请化为最简分数。

测试样例:
3
返回:[3,4]
import java.util.*;
 
public class Ants {
    public int[] collision(int n) {
        // write code here
        int total = 1<<n;
        if((total-2)%2!=0)  return new int[]{(total-2),total};
        return new int[]{(total-2)/2,total/2};
         
    }
}

 

import java.util.*;
 
public class Ants {
    public int[] collision(int n) {
        // write code here
        int numm = (int)Math.pow(2, n-1);
        int numz = numm - 1;
        int[] A = {numz,numm};
        return A;
    }
}

 

import java.util.*;
 
public class Ants {
    public int[] collision(int n) {
        // write code here
        int total = (int)Math.pow(2.0, n);
        int tem = gcd(total, total - 2);
        int[] res = new int[2];
        res[1] = total / tem;
        res[0] = (total-2) /tem;
        return res;
         
    }
     
    private int gcd(int a, int b){
         
        while(b != 0){
            int tem = b;
            b = a % b;
            a = tem;
        }
         
        return a;
    }
}

3随机函数

给定一个等概率随机产生1~5的随机函数,除此之外,不能使用任何额外的随机机制,请实现等概率随机产生1~7的随机函数。(给定一个可调用的Random5::random()方法,可以等概率地随机产生1~5的随机函数)

import java.util.*;
 
public class Random7 {
    private static Random rand = new Random(123456);
    // 随机产生[1,5]
    private int rand5() {
        return 1 + rand.nextInt(5);
    }
     
    // 通过rand5实现rand7
    public int randomNumber() {
        int res=30;
        while(res>20){
            res=5*(rand5()-1)+(rand5()-1);
        }
        return (res%7)+1;
    }
}

4随机01

给定一个以p概率产生0,以1-p概率产生1的随机函数RandomP::f(),p是固定的值,但你并不知道是多少。除此之外也不能使用任何额外的随机机制,请用RandomP::f()实现等概率随机产生0和1的随机函数。

import java.util.*;
 
public class RandomSeg {
    private Random rand = new Random(12345);
    public double f() {
        return rand.nextFloat();
    }
    // 请调用f()函数实现
    public double random(int k, double x) {
        double max=Double.MIN_VALUE;
        for(int i=0;i<k;i++){
            max=Math.max(max, f());
        }
        return max;
    }
}

5随机区间

假设函数f()等概率随机返回一个在[0,1)范围上的浮点数,那么我们知道,在[0,x)区间上的数出现的概率为x(0<x≤1)。给定一个大于0的整数k,并且可以使用f()函数,请实现一个函数依然返回在[0,1)范围上的数,但是在[0,x)区间上的数出现的概率为x的k次方。

import java.util.*;
 
public class RandomSeg {
    private Random rand = new Random(12345);
    public double f() {
        return rand.nextFloat();
    }
    // 请调用f()函数实现
    public double random(int k, double x) {
        double max = 0;
        for(int i = 0; i < k ; i++)
        {
            max = Math.max(max,f());
        }
        return max;
    }
}

6随机数组打印

给定一个长度为N且没有重复元素的数组arr和一个整数M,实现函数等概率随机打印arr中的M个数。

import java.util.*;
 
public class RandomPrint {
   public int[] print(int[] arr, int N, int M) {
        int[] res = new int[N];
        return res;
    }
}

 

import java.util.*;
import java.util.Random;
public class RandomPrint {
    private static Random rand = new Random(123456);
    public int[] print(int[] arr, int N, int M) {
          
         int[] result=new int[M];
         int index=N-1;
         for(int i=0;i<M;i++){
             int j=rand.nextInt(index);
             result[i]=arr[j];
             //把打印的数和最后的数交换位置
             int temp=arr[j];
             arr[j]=arr[index];
             arr[index]=temp;
             --index;
         }
         return result;
    }
}

7机器吐球

有一个机器按自然数序列的方式吐出球,1号球,2号球,3号球等等。你有一个袋子,袋子里最多只能装下K个球,并且除袋子以外,你没有更多的空间,一个球一旦扔掉,就再也不可拿回。设计一种选择方式,使得当机器吐出第N号球的时候,你袋子中的球数是K个,同时可以保证从1号球到N号球中的每一个,被选进袋子的概率都是K/N。举一个更具体的例子,有一个只能装下10个球的袋子,当吐出100个球时,袋子里有10 球,并且1~100号中的每一个球被选中的概率都是10/100。然后继续吐球,当吐出1000个球时,袋子里有 10 个球,并且1~1000号中的每一个球被选中的概率都是10/1000。继续吐球,当吐出i个球时,袋子里有10个球,并且1~i号中的每一个球被选中的概率都是10/i。也就是随着N的变化,1~N号球被选中的概率动态变化成k/N。请将吐出第N个球时袋子中的球的编号返回。

import java.util.*;
 
public class Bag {
    private int [] selected = null;
    private static Random rand = new Random(12345);
    private boolean flag=true;
    // 每次拿一个球都会调用这个函数,N表示第i次调用
    public int[] carryBalls(int N, int k) {
        if(flag){
            selected= new int[k];
            flag=false;
        }
        if(N<k)
            selected[N-1]=N;
        else{
            if(rand.nextInt(N)<k){
                selected[rand.nextInt(k)]=N;
            }
        }
       
         
         
        return selected;
    }
}

 

posted @ 2017-05-22 16:32  临江仙zhe  阅读(65)  评论(0)    收藏  举报