题目:
求一个分数,分子5位数(第1位不是0),分母也是5位数(第1位不是0),分子和分母这10个数正好由0到9这10个数字组成(不缺也不重复)。求最接近π值的那个分数
解法1(穷举法)
Sub getit()
Const num As Long = 3628800 ' 10!
Dim tt As Single, i As Long, j As Long, k As Long, temp1 As Long, temp2 As Long, pi As Single, diff As Single, out As String, temp As String
pi = 4 * Atn(1)
diff = 1
tt = Timer '开始计时
For i = 0 To num - 1
temp = 0
temp1 = i
For j = 2 To 10
temp2 = temp1 Mod j + 1
temp1 = temp1 \ j
temp = Left(temp, temp2 - 1) & j - 1 & Mid(temp, temp2)
Next
If temp Like "[3-9]####[1-3]####" Then
temp1 = Val(Left(temp, 5))
temp2 = Val(Right(temp, 5))
If Abs(temp1 / temp2 - pi) < diff Then diff = Abs(temp1 / temp2 - pi): out = temp1 & "/" & temp2
End If
Next
MsgBox out & "用时 " & Timer - tt & " 秒!"
End Sub
最后结果:=85910/27346
上述代码效率太低.
解法2(穷举法)
Sub Getit()
Dim pi As Single, diff As Single, i As Long, j As Long, temp As Long, s() As Byte, n As Byte, result As String, tt As Single
tt = Timer
pi = 4 * Atn(1)
diff = 1
For i = 31425 To 98765
ReDim s(9)
For j = 1 To 5
s(Mid(i, j, 1)) = 1
Next
If WorksheetFunction.Sum(s) = 5 Then
temp = Fix(i / pi)
For j = 1 To 5
s(Mid(temp, j, 1)) = 1
Next
If WorksheetFunction.Sum(s) = 10 Then
If Abs(i / temp - pi) < diff Then
diff = Abs(i / temp - pi)
result = i & "/" & temp
End If
End If
End If
Next
MsgBox result, vbInformation, "总计用时" & Timer - tt & "秒!"
End Sub
解法3(递归法)(yier_fang提供,http://club.excelhome.net/dispbbs.asp?boardid=2&replyid=978209&id=262029&page=1&skin=0&Star=1)
Dim lngFM As Long
Dim lngFZ As Long
Const PI = 3.1415926535
Dim dbl As Double
Dim kkk As Long
Dim intCK As Integer
Dim showW As Boolean
Dim Unums As String
Dim Lnums As String
Sub cnft()
Dim tm
tm = Timer
Application.ScreenUpdating = False
kkk = 0: lngFM = 0: lngFZ = 0
Unums = Cells(3, "H")
Lnums = Cells(3, "I")
dbl = 3.1415926535
intCK = Cells(3, "F").Value
showW = Cells(3, "E").Value
If showW Then UserForm1.Show
Call fs("", "")
Cells(1, 2).Value = lngFZ
Cells(2, 2).Value = lngFM
If lngFM = 0 Then
Cells(3, 2).Value = "无解"
Else
Cells(3, 2).Value = (lngFZ / lngFM)
End If
Cells(4, 2).Value = kkk
UserForm1.Hide
Application.ScreenUpdating = True
Cells(5, 2) = Format((Timer - tm), "0.0000") & "秒"
End Sub
Sub fs(ByRef FM As String, ByRef FZ As String)
kkk = kkk + 1
If showW Then
UserForm1.TextBox1.Text = "递归第..." & kkk & "...次"
DoEvents
End If
Dim i, j As Long
If Len(FM) = 0 Then
For i = 1 To 9
For j = 1 To 9
If i <> j Then
Call fs(CStr(i), CStr(j))
End If
Next j
Next i
ElseIf Len(FM) < 5 Then
If intCK = 1 Then
If ((FZ - 1) / (FM + 1)) > PI Then Exit Sub
If FM = 1 Then
If ((FZ + 1) / (FM)) < PI Then Exit Sub
Else
If ((FZ + 1) / (FM - 1)) < PI Then Exit Sub
End If
ElseIf intCK = 2 Then
'=======下面是手工的出口设置=========
If FZ / FM < Lnums Then Exit Sub
If FZ / FM > Unums Then Exit Sub
End If
For i = 0 To 9
If InStr(FM & FZ, i) = 0 Then
For j = 0 To 9
If InStr(FM & FZ & i, j) = 0 Then
Call fs(FM & i, FZ & j)
End If
Next j
End If
Next i
Else
If Abs((FZ / FM) - PI) < dbl Then
lngFM = FM
lngFZ = FZ
dbl = Abs((FZ / FM) - PI)
End If
End If
End Sub
解法4(递归法)(彭希仁提供:http://club.excelhome.net/dispbbs.asp?boardid=2&replyid=977506&id=262029&page=1&skin=0&Star=2)
Public pi
Public x
Public y
Public z
Public k As Long
Public st
Sub peng()
t = Timer
pi = 4 * Atn(1)
x = 10
st = 0
Call caii("", 0)
MsgBox (y & "/" & z & "=" & y / z & "递归" & st & "次,耗时" & Timer - t & "秒")
End Sub
Sub caii(a, i)
st = st + 1
m = 0
If i = 1 Then m = 3
For j = m To 9
If Not (a Like "*" & j & "*") Then
If i + 1 = 5 Then
k = a & j
If k > 31415 Then
kp = Round(k / pi)
If Abs(k / kp - pi) < x Then
h = k & kp
For n = 0 To 9
If Not (h Like "*" & n & "*") Then Exit For
Next n
If n = 10 Then
x = Abs(k / kp - pi)
y = k
z = kp
End If
End If
End If
Else
Call caii(a & j, i + 1)
End If
End If
Next j
End Sub
解法5(回溯法)
Sub getit(ByVal target As Single) 'target is a single number between 1~98765\10234
Dim n As Byte, m As Byte
Dim i As Integer, j As Integer, t As Integer, a(), fenmu As Long, fenzi As Long, max As Long, temp As String, result As Long
m = 4: n = 9
diff = 1
tt = Timer
max = int(98765/target)
ReDim a(m)
For i = 1 To m
a(i) = -1
Next
Do
a(t) = a(t) + 1
If a(t) > n Then
t = t - 1
Else
For i = 0 To t - 1
If a(t) = a(i) Then Exit For
Next
If i = t Then
If t = m Then
fenmu = Join(a, "")
fenzi = Round(fenmu * target)
temp = fenzi & "/" & fenmu
If Abs(fenzi / fenmu - target) < diff Then
For j = 0 To 9
If InStr(temp, j) = 0 Then Exit For
Next
If j = 10 Then diff = Abs(fenzi / fenmu - target): result = fenmu
End If
End If
If t < m Then t = t + 1: a(t) = -1
End If
End If
If fenmu > max Then Exit Do
Loop Until t = -1
Debug.Print "Target: " & target & vbCrLf & "Result: " & Round(result * target) & "/" & result & vbCrLf & "Error: " & diff & vbCrLf & "Lapsetime: " & Format(Timer - tt, "0.00000") & " seconds" & vbCrLf
End Sub
Sub macro1()
getit Sqr(2)
getit Sqr(3)
getit Exp(1)
getit 4 * Atn(1)
getit 5.6789
End Sub
返回:
Target: 1.414214
Result: 95103/67248
Error: 4.76071359769127E-07
Lapsetime: 0.20313 seconds
Target: 1.732051
Result: 93820/54167
Error: 1.03205265816492E-07
Lapsetime: 0.13867 seconds
Target: 2.718282
Result: 87159/32064
Error: 4.39718097983719E-07
Lapsetime: 0.06445 seconds
Target: 3.141593
Result: 85910/27346
Error: 1.79341409058684E-07
Lapsetime: 0.04492 seconds
Target: 5.6789
Result: 95082/16743
Error: 1.08244854411521E-05
Lapsetime: 0.01563 seconds
分享到:
相关推荐
夏道行用连分数的方法证明,在所有分母不超过 8000 的分数当中,和 π 最接近的仍然是密率。如果有分数 q/p 比 355/113 更接近 π,则一定会有,p,q 为正整数,求解可得 p>16586。可见密率的分母不大而精确度很高。 ...
随着迭代次数的增加,计算结果会越来越接近真实的π值。 在实际编程中,我们还可以优化这个过程,比如使用并行计算加速级数求和,或者采用更高效的级数公式。例如,Bailey-Borwein-Plouffe(BBP)公式允许直接计算...
当α趋于π/2时,FrFT接近于传统的傅立叶变换,揭示信号的频率成分。 土耳其算法的基本步骤包括以下几个部分: 1. **分解**: 将分数阶傅立叶变换矩阵分解为一系列基本矩阵的乘积。 2. **快速算法**: 利用这些基本...
5. **π值估算**:根据比例乘以4即可得到π的近似值,因为球面积占正方体面积的比例是π/4。 `license.txt`文件则包含了脚本的许可信息,可能涉及代码的使用、修改和分发的条款。 在实际应用中,为了提高精度,...
这种方法是通过将一个正方形内接于一个圆,然后不断分割成更小的正多边形,当边数趋于无穷大时,多边形的周长接近圆的周长,从而逼近π的值。具体来说,可以使用著名的马赫林级数或者莱布尼茨公式等无限级数来计算π...
算法的核心概念首先从LFM信号的数学模型开始,通常表示为s(t) = exp{j(2πf0t + πk0t^2)},其中f0为初始频率,k0是调制斜率,也就是调频率。该算法的独特之处在于引入了二次相位函数(QP function)的概念,通过这...
在本教程中,遗传算法被应用于求解函数 `y=x*sin(10*π*x)+2.0` 的最大值。这个函数是一个非线性函数,其最大值可能不那么容易通过传统数学方法找到。 遗传算法的基本步骤如下: 1. **初始化种群**:首先,随机...
2. 探索“割圆术”的算法,这是一种无限逼近圆周率的方法,通过不断倍增圆内接正多边形的边数来逐步接近圆的周长与直径的比例,即圆周率π。 过程与方法目标强调: 1. 将抽象的数学问题转化为具体步骤化的过程,...
程序会累加这些项,随着项数增加,结果会越来越接近π/4,乘以4即可得到π的近似值。 `README.txt`文件通常包含项目的说明、使用指南或作者的注释。在这个上下文中,它可能解释了所用算法的原理,如何编译和运行...
这些测试可能会覆盖各种输入值,包括小数、大数以及接近整数的值,确保算法在各种边界条件和极端情况下的表现。 总的来说,这个C代码库提供了一个实用工具,可以用于在C程序中高效地计算伽马函数的对数,这对于需要...
6. **算法与程序**:根据算法框图,执行流程是将t初始化为1,然后从2到5循环,每次乘以i的值,最后输出t的值。执行完后,t的值为1*2*3*4*5=120,对应选项D。 7. **频率分布直方图**:中间小长方形面积占其他10个的1...
这个级数随着项数的增加逐渐接近π的真实值,但永远不会完全等于π,因为π是无理数。MATLAB脚本“mypiplottergregory.m”将帮助我们可视化这一过程,展示随着项数增加,级数和π之间的差距是如何减小的。 在MATLAB...
7. **`round(x)`**:四舍五入到最接近的整数。 8. **`fix(x)`**:将`x`四舍五入到零的方向,即负数朝正方向,正数不变。 9. **`floor(x)`**:向下取整,即向负无穷方向取整数。 10. **`ceil(x)`**:向上取整,即...
这个公式表明,你可以无限地加减分数序列,每两个项的绝对值都会逐渐减小,从而逐渐接近π/4。因此,程序可能会包含一个循环,不断地累加或累减这些分数,然后乘以4来得到π的近似值。 在`README.txt`文件中,可能...
- `round(x)`:四舍五入`x`到最接近的整数。 - `fix(x)`:舍去小数部分,返回最接近的整数。 - `floor(x)`:向下取整,返回小于等于`x`的最大整数。 - `ceil(x)`:向上取整,返回大于等于`x`的最小整数。 - `...
- 抛硬币正反面出现次数比最可能接近1:1,因为硬币正反面出现的概率应该是相等的。 - 正方形内最大圆的面积是正方形面积的π/4,约等于78.5%。 6. **分数、百分比及运算**: - 质量、时间和比率的转换。 - 黄豆...
每增加一项,级数的和会更接近π/4。因此,我们可以编写一个循环,不断累加这些项,然后乘以4来得到π的近似值。Python代码示例如下: ```python def gregory_leibniz(n_terms): pi_approx = 0 for i in range(1,...
1. 在计算公式 `(1 + 1/t)^t` 直到 `t` 接近无穷大时,形参 `e` 的值通常为一个很小的正数,例如 `1e-3`,这时可以利用泰勒级数或者牛顿迭代法求解,函数返回值为 `0.551690`,表示在 `t` 趋向于无穷大时,该公式的...
3. 通过扇形占比计算,360° - 45° * 2 = 270°,占了3/4,所以30天中有3/4 * 30 = 22.5天是雨天,选择最接近的选项,即21天。 4. 服装店的盈亏计算,100元赚20%是120元,亏本20%是80元,所以总亏损10元,是亏本。 ...