答案在文章结尾,不感兴趣的可以直接看答案
也就是昨天在渣男开车群中惊现一张照片。4只鸭子!
然后一群渣男开始了激烈的讨论,有说1/8的 有说3/4的 有说1/3的…反正说什么的都有
唉你说都是男的好好滴妹子不聊,怎么讨论起来数学题了?好好的厨子不切菜,反倒玩起了乐器?我非常不屑于他们的行径,并积极的参与到了讨论之中。
我向着Java高声呐喊到
来吧!赐予我让他们闭嘴的力量吧!
一上来就暴力求解:思路是
只要存在两点的连线将圆分为大小两半,使其余两点在较小半侧,那么就判定为真,否则为假。写了半天感觉算下来的有点奇怪这里就不多说了。
换了一个思路,每一只鸭子都能与圆心用来唯一的确定一条直线,只要剩下三只在这条直线的同一侧就算在一半内。
上来我就定义了一个Point类,可以随机生成点出现在以原点为圆心,1为半径的圆内的点
class Point {
private double x;
private double y;
//假设圆半径为1,圆心为原点
public Point() {
double a = 0;double b = 0;
do{
x = Math.random()*2-1;
y = Math.random()*2-1;
}while (outOfCircle(x,y));
}
@Override
public String toString() {
return "["+x+","+y+"]";
}
public Point(double x, double y) {
this.x = x;
this.y = y;
}
private boolean outOfCircle(double a, double b){ return a*a+b*b>1; }
public double getX() {
return x;
}
public double getY() {
return y;
}
}
直线的类我一开始想的比较复杂包含了截距b (其实不怎么需要)其类为Line
class Line {
private double k;
private double b;
public Line(double k, double b) {
this.k = k;
this.b = b;
}
public double getK() {
return k;
}
public double getB() {
return b;
}
public double getXWhenY0() {
return -b / k;
}
public double getYWhenX0() {
return b;
}
}
以下是函数的实现部分
public class Main {
public static void main(String[] args) {
int in = 0;
int count =10000000;
for (int i = 0; i < count; i++) {
Point[] ps = build4Duck();
if (isOrNotInHalf(ps)) {
in += 1;
}
}
System.out.println("经过"+count+"实验,其中4只鸭子都在一侧的情况为"+in+"次");
System.out.println("概率为:"+(double)in/count);
}
private static Point[] build4Duck(){
Point[] ps = new Point[4];
for(int i=0;i<ps.length;i++)
ps[i] = new Point();
return ps;
}
private static boolean isOrNotInHalf(Point[] ps) {
for(int i = 0;i<ps.length;i++){//跟距一个点坐标和圆心将圆分成两半
Line line = getLine(new Point(0,0),ps[i]);
if(line==null)return false;
boolean isInHalf = true;
//找到其余的第一个点是在直线上方还是下方
int ano = (i==0)?1:0;
boolean onOrDown = ps[ano].getY()-line.getK()*ps[ano].getX()>0;//斜率b是否大于0
for(int j = ano+1;j<ps.length;j++){
if(i==j)continue;
isInHalf = isInHalf
&&(onOrDown==(ps[j].getY()-line.getK()*ps[j].getX()>0));//其余各点是否ano位置相同
}
if(isInHalf)return true;
}
return false;
}
private static Line getLine(Point one, Point ano) {
double x1 = one.getX();
double y1 = one.getY();
double x2 = ano.getX();
double y2 = ano.getY();
//斜率y = kx + b
double k = ((double) (y2 - y1)) / (x2 - x1);
if (k == 0) return null;
double b = y1 - k * x1;
return new Line(k, b);
}
}
运行结果是
当当当当~完美解决!
四只鸭子在同侧的概率为
1/2
没想到吧居然有一半的几率4只鸭子在同一侧。
然后呢。某群友在谷歌搜索Duck Pond Probability得到了外国友人的解答思路
翻译一下,设第“1”只鸭子恰好在0°的位置。剩下的每只鸭子都可能与这只鸭子在同侧的概率都是1/2,然而每只鸭子都可能当这个鸭王。所以结果为4*(1/21/21/2)
百度怎么都搜不到的题谷歌居然一下就解决了。这对我打击有点大…以后一定要好好用谷歌搜索。