一个骰子有6面,概率均匀,小弟我怎么选择7件事

一个骰子有6面,概率均匀,我如何选择7件事?
一个骰子有6面,概率均匀,我有7件事要随机均匀选择,如何扔?

如果我有4件事,5件事,8件事,9件事,10件事,
...n件事要选择,那

么我如何用最少的扔掷次数,来做到均匀分布?

------解决方案--------------------
java代码,思路是上面几位提到的6进制。测试结果呈均匀分布。

Java code


import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Random;

public class TestN {

    public static void main(String[] args) {
        int things = 1600;//事件数
        HashMap<Integer,Integer> map = new HashMap<Integer,Integer>();
        int whatTodo = whatShouldIDo(things);
        
        //Begin:以10万次为统计结果,发现是均匀分布的
//        for(int t =0;t<100000;t++){
//            int whatTodo = whatShouldIDo(things);
//            map.put(whatTodo, map.get(whatTodo)==null?1:map.get(whatTodo)+1);
//        }
//        Iterator<Integer> iterator = map.keySet().iterator();
//        while(iterator.hasNext()){
//            Object key =iterator.next();
//            System.out.println(key+"->"+map.get(key));
//        }
        //End
    }

    private static int whatShouldIDo(int things) {
        float percent = 0.9f;//精度 
        int tongSize = 0;
        int MaxTime = 10;
        int j = 0;
        int times=0;//需要扔色子次数
        int total=0; //扔出来N次的色子总和
        for(int i=1;i<MaxTime+1;i++){
            tongSize =  (int) Math.pow(6, i);
            times++;
            j = tongSize/things*things;
            System.out.println("查看"+times+":"+tongSize+"->"+j);
            if(j>=tongSize*percent){
                System.out.println("有合理的桶存在!需要扔色子次数为"+times);
                break;
            }
        }
        
        System.out.println("桶的大小:"+tongSize);
        System.out.println("输入为"+things+"的任务离桶最近的数:"+j);
        System.out.println("舍弃数为:"+(tongSize-j));
        System.out.println();
        
        Random r = new Random();
        StringBuffer sb = new StringBuffer();
        ArrayList shanZi = new ArrayList() ;
        while(true){
            total = 0;
            shanZi.clear();
            for(int time=0;time<times;time++){
                int now=r.nextInt(6);
                total=total*6+now;
//                System.out.println("第"+(time+1)+"次:"+now+"->"+total);
                System.out.println("第"+(time+1)+"次,你扔的骰子为:"+(now+1));
                shanZi.add(now);
            }
            if(total<=j){
                break;
            }else{
                System.out.println(total+"不在有效范围内,作废!重新开始扔");
            }
        }
        //输出计算结果
        //现实中的色子数为[1,6],计算时用[0,5]表示
        for(int index=0;index<shanZi.size();index++){
            int pow = shanZi.size()-index-1;
            sb.append(shanZi.get(index)+"*power(6,"+pow+")");
            if(pow!=0){
                sb.append("+");
            }
        }
        System.out.println(sb.append("=").append(total));
        System.out.println("取模:"+(total%things));
        if(total%things==0){
            System.out.println("色子决定人生:你要做的是第"+things+"件事");
        }else{
            System.out.println("色子决定人生:你要做的是第"+(total%things)+"件事");
        }
//        //生成模板图形
//        for(int i=1;i<tongSize+1;i++){
//            System.out.print(i+"\t" );
//            if(i%things==0){
//                System.out.println();
//            }
//        }
        return (total%things);
    }
}

------解决方案--------------------
C/C++ code
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <dirent.h>
#include <sys/stat.h>
#include <string.h>

#define EVENT_MAX        100

static int dice_radix; /* 基数,比如7件事色子有6面,则基数为9 */
static int event_count; /* 事件数目,比如这里的7、4、5、8、9、10 */
static int throw_times; /* 所需要掷色子次数,比如此题事件7次则需要掷2次 */
static int dice_max; /* 色子的面数,比如6 */

int init_rand(int event_count, int dice_max_count);
int get_rand(void);

int main(int argc, char *argv[])
{
    int i;
    int ret[EVENT_MAX];
    memset(ret, 0, sizeof(ret));
    init_rand(7, 6);
    printf("%d, %d, %d, %d...\n", dice_radix, event_count, throw_times, dice_max);
    for(i=0; i<10000; ++i) {
        ret[get_rand()]++;
    }
    int total = 0;
    for(i=0; i<event_count; ++i) {
        total += ret[i];
        printf("event[%2d]=%4d...\n", i, ret[i]);
    }
    printf("\ntotal=%d...\n", total);
    return 0;
}

static time_t rand_pip;
int init_rand(int count, int dice_max_count)
{
    dice_radix = dice_max_count;
    event_count = count;
    throw_times = 1;
    dice_max = dice_max_count;
    if(count<=0) {
        return -1;
    }
    while(dice_radix < count) {
        ++throw_times;
        dice_radix *= dice_max_count;
    }
    while(dice_radix%count!=0) {
        ++count;
    }
    dice_radix = count;
    rand_pip = time(NULL);
    return 0;
}

int get_rand(void)
{
    int ret;
    int i;
    do {
        rand_pip += 100;
        srand(rand_pip);
        ret = 0;
        for(i=0; i<throw_times; ++i) {
            ret *= dice_max;
            ret += rand()%dice_max;
        }
        ret = rand()%dice_radix;
    } while(ret>=event_count);
    return ret;
}