在java中公平地生成和分发随机数

时间:2014-04-11 10:32:07

标签: java

嗨,我一直试图想出这个问题

彩票公司每周都会向获奖选手分享奖品。大多数星期,不止一个参赛者获胜,在这种情况下,他们试图尽可能公平地分享奖品。他们的奖品分配办公室已聘请您编写一个程序,用于以最公平的方式分发奖品。

你编写的程序应该有两行输入:

  • 以逗号分隔的本周奖品价值列表
  • 本周获奖者的逗号分隔名称

例如,输入可以是: 100,800,200,500,400,1000 约书亚马赫什,莉莲

然后,程序应输出最公平的奖品分配,为每个获胜者显示一行,并分配奖品的价值。例如,给定上面的输入,输出可以是:

  • 约书亚:100400500
  • 马赫什:1000
  • 莉莲:800200

上面的例子提供了一个完美的解决方案,所有获奖者都获得相同的奖品价值(每个总价值1000)。在许多情况下,这是不可能的,但所有奖品必须分发,不能分开。您的部分工作是决定如何为这些案例定义“公平”。例如,给定输入

400400500600

巴里,希拉,奥尼,Wekesa

以下是可接受的输出,因为没有更公平的分布:

  • 巴里:400
  • 希拉:400
  • 奥尼:500
  • Wekesa:600

我正在使用java,到目前为止,这是我提出的

import java.util.Scanner;
import java.util.Arrays;

public class Main {
    private static String amounts;
    private static String names;

    public static void main(String[] args) {
        Scanner userInput = new Scanner(System.in);

        System.out.print(
                "Please enter the lottery amounts separated by commas: ");

        if (userInput.hasNext()) {
            amounts = userInput.next();
            // System.out.println("You entered: " + amounts);
        }

        System.out.print("Please enter the contestants names: ");

        if (userInput.hasNext()) {
            names = userInput.next();
            // System.out.println("You entered: " + names);
        }

        String amountArray[] = amounts.split(",");
        String nameArray[] = names.split(",");

        award(nameArray, amountArray);
    }

    // Method that awards the amounts to the winners
    public static void award(String names[], String amounts[]) {
        int randomAmount;
        int randomName;

        for (int i = 0; i < amounts.length; i++) {
            randomAmount = (int) (Math.random() * amounts.length);
            int usedValue[] = new int[amounts.length];
            usedValue[i] = randomAmount;
            if (checkValueUsed(randomAmount, usedValue)) {

                randomName = (int) (Math.random() * names.length);
                int usedName[] = new int[names.length];

                System.out.println(names[randomName] + " = "
                        + amounts[randomAmount]);
            } else {
                break;
            }
        }
    }

    private static boolean checkValueUsed(int currentState, int[] myArray) {
        boolean found = false;

        for (int i = 0; !found && (i < myArray.length); i++) {
            if (myArray[i] == currentState) {
                found = true;
            }
        }
        return found;
    }

    private void checkUsedValue(int currentState, int[] myArray) {
        for (int i = 0; (i < myArray.length); i++) {

            if (myArray[i] == currentState) {

            }
        }
    }
}

我的公平想法是选择一个随机数量并将其分配给随机获胜者。

2 个答案:

答案 0 :(得分:2)

1)这看起来像是面试/考试问题。我不是要判断,但......真的吗? 2)你对公平的想法不是预期的。通过给出的例子,公平意味着所有奖品都是分配的,每个获奖者总数尽可能相近 3)从上面 - 这是一个已知的问题。 greedy algorithm可能表现良好。 (我真的不明白为什么不这样做,除非你对问题的优化部分有所了解)

答案 1 :(得分:2)

对于“公平”分发,你可以尝试这样的事情:

  1. 随机订购获奖者。
  2. 为每位获奖者分配当前最高奖金;所以使用你的第一个例子,获胜者获得1000,获胜者2获得800,获胜者3获得500。
  3. 如果还有奖品需要分发,除了第一个获胜者之外,为他们分配当前最高可用奖金,不超过第一个获奖者的总奖金;获胜者2将获得200(匹配1000名获胜者),获胜者3获得400(获得900)。
  4. 重复第三步,直到没有奖品或没有分配奖品;获胜者三获得100以匹配其他两个中的1000个。
  5. 如果仍有奖品需要分配,请根据总奖金按降序对获奖者进行排序,并开始为除第一名获奖者以外的所有奖品分配最低奖品。
  6. 重复步骤5,直到分配完所有奖品。