Mathematics × Programming Competition #7 數學 × 程式編寫比賽 (第七回)数学、编程两种方法 Mathematics, Programming 2 methods

in #cn7 years ago (edited)

@kenchung 设计的[Question] Mathematics × Programming Competition #7 [問題] 數學 × 程式編寫比賽 (第七回),对我来说,这个题已经非常难了。不过我还是尝试分别用数学方法和程序的方法来解答这个题:

(一)数学方法

我来说说我整个思路哈。

1. 分析角的变化

在正方形中,任意取一点。与正方形下边的两个点相连接。

显然,这个点越往下,夹角越大;这个点越往上,夹角越小。如下图:

1.jpg

其中,有一个角是120度。而这个点在左右移动时,在不同的高度上,可以形成不同的120度角。把这些120度角的顶点连接起来,形成的轨迹,如下图:

2.jpg

2. 找到临界线

如上图,这是一个弧形,圆形的一部分。只有圆,弧上的圆周角都是120度。初中数学,等弦对等角。

而这个弧线,就是临界线。正方形内部,弧线上方的点,与正方形下边连接形成的顶角,显然都小于120度。

On the arc, the angle in a circular segment is 120°.

Above the arc, the angle is lese than 120°, and below the arc, the angle is more than 120°.

3. 确定范围

那么,相应的,对应正方形的四条边,分别可以绘制四条弧线,而这这四条弧线夹的部分:

左弧线的右侧、右弧线左侧、上弧下的下方、下弧线的上方,同时满足这四个条件,在正方形内部的部分,也是同时与正方形各点,所夹顶角小于120°的部分啦,如下图:

3.jpg

4.计算阴影面积

(1)计算圆的半径

把圆画出,正方形的边长是弦,弦所对的圆周角是120度,所以弦所对的大、小圆心角分别为240度和120度。

把正方形的边长设为1。圆的半径计算如下图:

4.jpg

接下就是计算面积啦。

(2)计算粉色弓形面积

5.jpg
这里,三角形面积计算使用了一下正弦定理哈,发公式太费事了,大家自行百度或谷歌吧。

(3)计算蓝色弓形面积

如图:
6.jpg

在等腰三角形AOB中,∠AOB=120°。所以∠BAO=30°。

由于AC是正方形对角线,所以角∠AB=45°。所以∠QAO=∠QAB+∠BAO=45°+30°=75°

三角形AOQ是等腰三角形,所以角∠QO也等于75°。

扇形AOQ的顶角AOQ是180-75-75=30°。


ΔAOB is a isoceles triangle
∠AOB=120°
=> ∠BAO=30°


AC is the diagonal
=> ∠AB=45°


①②=>∠QAO=∠QAB+∠BAO=45°+30°=75°


③, ③, ΔAOQ is a isoceles triangle
=>∠AOQ=180°-2×75°=30°

所以蓝色小弓形的面积计算如下图:

7.jpg

(4)计算阴影面积

阴影面积=正方形面积-4X粉色弓形面积+8X蓝色弓形面积=0.21255

因为,减粉色时,相交的小叶片被重复减了四块,即8块蓝色弓形

(4)计算概率

概率=阴形面积/正方形面积=0.213/1=0.21255

四舍五入0.213或者21.255%

(二)编程方法


我就是利用PHP的反正切函数atan()

同样还是把正方形边上看作1,把点距离正方形一个点的距离设为 $i $j,为了提高精度,每0.0001增加一点。

因为从每个端点出发的情况都是相同的,所以我作循环的时候就增加到0.5,这样能减少四分之三的运算量。

为了减少运算量,我用四层if嵌套。

<?php
$up=2*pi()/3;
$m=0;
$n=0;
for($i=0.0001; $i<0.5; $i+=0.0001)
{
    for($j=0.0001; $j<0.5; $j+=0.0001)
    {
        $m++;
        if(atan($i/$j)+atan((1-$i)/$j)<=$up)
        {
            if(atan($j/$i)+atan((1-$j)/$i)<=$up)
            {
                if(atan($i/(1-$j))+atan((1-$i)/(1-$j))<=$up)
                {
                    if(atan($j/(1-$i))+atan((1-$j)/(1-$i))<=$up)
                    {
                        $n++;
                    }
                }
            }
        }
    }
}
echo $n/$m;
?>

我这个是暴力的方法,我感觉并不好,期待其他朋友更简便的编程算法。

算了我调大点精度吧,不然太暴力了,我在本地环境下运行都特别慢。


把精度从0.0001调到0.0005:

<?php
$up=2*pi()/3;
$m=0;
$n=0;
for($i=0.0005; $i<0.5; $i+=0.0005)
{
    for($j=0.0005; $j<0.5; $j+=0.0005)
    {
        $m++;
        if(atan($i/$j)+atan((1-$i)/$j)<=$up)
        {
            if(atan($j/$i)+atan((1-$j)/$i)<=$up)
            {
                if(atan($i/(1-$j))+atan((1-$i)/(1-$j))<=$up)
                {
                    if(atan($j/(1-$i))+atan((1-$j)/(1-$i))<=$up)
                    {
                        $n++;
                    }
                }
            }
        }
    }
}
echo $n/$m;
?>
Sort:  

你不要再叫我偶像了,你就是我的偶像。

我那天算了一下午,今天ps这几个图又p了一上午。。。我来的时候排列组合那题,你那个数学答案我想了两天!!!

我就是使劲算使劲算的。

偶像你不要调侃我。。。。。

你就应该悄悄的坐在一旁,让别人看——不需要出动偶像本人,你的粉丝都会做题。

@TVB 频道更新换代升级了,服。

坛兄这么忙还能reply我,我乐得都开花了——虽然只能是狗尾巴花哈哈哈

暴力方法可以把这个正方形点阵化(根据精度可以细分网格),形成一个总点数,然后计算每一个点形成的内角,只要有一个大于120度,就计为1,否则讲为0,最后就得到大于120度的点的总数,剩下的点数就是都不大于120度,这样的比率就出来了,也就是概率。

看了你的算法,应该是和我这个一样的思路。

是的,哈哈哈,坛兄果然是博学and智慧!你们不要表现得太卓越了,我已每天嫌弃我老公了。

好认真的解答!!点赞!!

谢谢!!

啧啧,虽然我数学以前是学霸(先自夸一下),但看到题以后,我的老本都忘完啦!

好詳盡的解釋呀,早知我都不用花時間製作題解了,你寫得比我的題解更仔細了,哈哈

我就會初中數學,高中以後我就墮落了。謝謝老師誇獎。

Thnx @tvb for putting this info all together.

自己沙发一下吧,做图太累了,早知道拿个纸画下来直接拍照得了。。。。累屎我了。

看完觉得我数学白学了!

这就初中数学,我高中就堕落了,我也就会这点,对我来说这也是难如登天呀。

完了,感觉以后辅导儿子功课是胜任不了

我们辅导就是直接教怎么做题。
专业的老师,会教孩子如何去思考问题和解决问题。

所以,作自己擅长的事就行了,请老专业师来辅导儿子,效果更好。

太强了!! 看完覺得我的解法太懶惰了!

我是不知道有这么高级的工具,要知道,我也就不用算了,好费事呀。

Coin Marketplace

STEEM 0.17
TRX 0.13
JST 0.027
BTC 59232.68
ETH 2638.71
USDT 1.00
SBD 2.44