苹果公司的iPod取得了很大的商业成功。外观精巧、颜色多样、时尚现代的iPod Shuffle深受果粉尤其是年轻人的喜爱。由于形状限制,Shuffle没有显示屏,故不能进行选歌的操作,只能使用iTune预设的顺序或选择机器内置的“随机”播放模式。
然而,就是这个看似简单的“随机”播放模式,收到了很多质疑(ref):人们发现经常有些首歌被听了多遍而另一些歌却一次都没有被听到过。难道苹果公司的程序出了问题?在解决这个问题前,先看看另一个问题“生日悖论”吧。
生日“悖论”是指,如果一个群体里有23个或23个以上的人,那么至少有两个人的同一天过生日的概率要大于50%。这就意味着在一个30人的班级中,存在两人生日相同的可能性更高。如果你以前的班级曾经做过类似的调查,你会发现结果不容质疑。从引起逻辑矛盾的角度来说生日悖论并不是一种悖论, 只是因为这个数学事实与一般直觉相抵触,所以称它为一个“悖论”。 大多数人会认为,23人中有2人生日相同的概率应该远远小于50%。数学上可以证明这个概率值大约等于50.7%。要是50人的班级,这个概率大约是97%。对于60或者更多的人,这种概率甚至要大于99%。下面这个游戏可以帮助你了解这个问题。
生日悖论游戏
计算与此相关的概率被称为生日问题, 在这个问题之后的数学理论已被用于设计著名的密码攻击方法:生日攻击。其实苹果的Shuffle的问题恰恰不是不随机而是真正的随机造成的,只是与人们对“随机”的直觉冲突了。
本题目要求你对这个问题进行模拟:假设你的MP3播放器里一共有N首歌曲,由于启用了随机播放模式,每次自动选下一首歌曲的时候,每首歌曲都以相同的概率被选中,不管该歌曲是否已经被播放过了。
通过蒙特卡洛方法模拟可以近似估计出平均播放多少首歌曲后,你将会听到已经听过的歌曲。
输入:
歌曲总数量N,蒙特卡洛模拟的次数T(都是整数)
输出:
取整后的平均次数(为了方便系统进行自动判定,故请输出整数。取整方法:(int)(x+0.5))
样例输入:
365□10000↵
样例输出:
25
import java.util.Scanner;
/*
* 随机播放和生日"悖论"
*/
public class Main {
//蒙洛随机数处理程序
public static int deal(int songNum, int mlCount) {
int songSum = 0;
double d = 1.0 / songNum;
for (int i = 0; i < mlCount; i++) {
Boolean[] b = new Boolean[songNum];
for (int j = 0; j < songNum; j++) {
b[j] = false;
}
Boolean flag = false;
int mlCountTemp = 0;
while (!flag) {
double ranNum = Math.random();
int iTemp = (int) (ranNum / d);
mlCountTemp++;
if (iTemp == songNum) {
iTemp--;
}
if (b[iTemp]) {
songSum += mlCountTemp;
break;
} else {
b[iTemp] = true;
}
}
}
double mlNum = (double)(songSum) /(double) mlCount;
//平均数
int averNum = (int) (mlNum + 0.5);
return averNum;
}
public static void main(String args[]) throws Exception {
Scanner cin = new Scanner(System.in);
int songNum = cin.nextInt();//歌曲数
int mlCount = cin.nextInt();//play次数
System.out.println(deal(songNum, mlCount));
}
}