趣味算法题一

萌到你眼炸
562次浏览
2020年09月29日 07:42
最佳经验
本文由作者推荐

佛经名言-会计毕业实习报告

2020年9月29日发(作者:白大华)


趣味算法题一

在网上回答一个有关算法的问题,觉得有点启发意义,就把它 写在这里,与大家共享,
是心血来潮之解,大都不会是最好的解法,权作抛砖引玉吧。
题目原文的意思如下:
100可以表示为带分数的形式,比如:

其中有一些特殊的情况,例如:

注意上面举的两个例子的特征:带分数中数字1~ 9分别只出现一次(不包括0),类似
的带分数,100有11种表示方法。
题目要求: < br>从键盘输入一个正整数N(N<1000*1000),程序输出该数用数码1~9不重复不遗漏地
组成带分数表示的全部种数。
注意:不要求输出每个表示,只统计有多少表示法,例如,程序运行时 输入100,程序
在屏幕上输出11。
整个算法采用枚举算法的方法。
枚举算法: 就是一一罗列问题的可能的所有解,并且一边罗列一边去检验这个解是否问
题的正真解,是的就采纳它, 不是的就抛弃它。

一.数学分析
对于一个正整数N,可以表示为带分数的形式如下;

从数学知识的要求来说,其中规定:I的范围:[1,N-1],J >=1,例如:
对于N = 3,有:

所以,根据数学知识可以知道,这样的形式有无穷多个结果,„„。
从题目要求分析,由于有:带分数中数字1~~~~9分别只出现一次(不包括0),这样结
果就变成 了有限个了,题目要求满足:
I、J、M三个数字正好使用到了1、2、3、4、5、6、7、8、9 这9个数字,且仅使用一
次。
用程序实现枚举算法,往往是用循环来实现一一列举,用选择来实现逐步检验。
比如:对于100,它的I值可以是1,2,3,„„99,它的M与J值:
当I = 1, 有:991,1982,2973,„„,随着分子、分母的递增,它们的位数也在逐


步 增多。
从以上分析,I采用记数循环,起始值为1,终止值为N-1;而J采用标志循环,终止循环的标志是:I、J、M三个的数字的位数和超过9(这个是本题的关键)。
在上述循环过程中, 当I,M,J三者的位数和等于9的时候,就判断,这9个位置上的
数字,是否刚好使用到1-9。 < br>也就是说在上述一一列举的过程中,并非需要都去检验,只有当满足正好是9位数字的
时候,去检 验。
问题:如何检验呢?

是符合要求的解,还有“135792468”也是符合要求的解。
通过数学分析知道,1- 9个数字的全排列,都是符合要求的解,显然用全排列的思路去
检验,是十分费时间的。
突然 想到,把这些符合要求的数字,按照升序排列,就只能是“123456789”,反之如
果9个数字中 有数字重复的就不等于“123456789”。
所以检验的算法如下:
1,把I、M、J三个数字转换成字符串,然后连接成一个字符串Lins。
2,把Lins用Split()函数,拆分保存到一个数组d()。
3,对数组d(),进行升序排列。
4,将排列后的数组d(),连接成新的字符串Lins。
5,最后进行检验判断。

二.算法思路:
(一)主程序的算法:
分析:有关系式:M = J *(N – I)
1.读取给出的N。
2.I = 1
3.如果I = N 就转向步骤11
4. J = 1,(J是分母);M = J*(N - I);W = I的位数 + J的位数 + M的位数
5. 如果 W > 9 就转向 9
6. If W = 9 Then
判断I,J,M三个数字是否正好使用1-9各一次;
如果是的:G = G + 1 ‘用G存放满足条件的个数
End If
7. J = J + 1;M = J*(N - I);W = I的位数 + J的位数 + M的位数
8. 转向5
9. I = I + 1
10.转向3
11.输出 G

(二)检验I、J、M三个正整数是否正好使用1-9各1次的自定义函数的算法:
首先,从主程序里可以看到,此时I、J、M三个正整数的位数和为9。
1.个正整数I、J、M转换成字符串类型,把他们连接成一个字符串;


例如:I = 81,J = 297,M = 5643,得到字符串Lins = “812975643”
2.为了判断是否正好使用1-9各一次,方法肯定不是唯一,我的方法是:
把变量Lins里的字符,从小到大排列,排列后与”123456789”比较是否相等。
具体实现:利用VB6里的Split()函数,把这9个字符拆分到数组的9个元素里,再进< br>行升序排序,再连接成字符串。
3.如果比较结果一致,函数返回TRUE,反之函数返回FALSE。

以上就是整个算法的思路:

完整的代码:
窗体上添加一个文本框和一个按钮,文本框用来接受输入N的值。
Option Explicit

Private Sub Command1_Click()
Dim i As Long
Dim j As Long
Dim m As Long
Dim W As Integer
Dim N As Long
Dim G As Integer
d = False
G = 0
N = Val()
For i = 1 To N - 1
j = 2
m = j * (N - i)
W = Len(CStr(i)) + Len(CStr(j)) + Len(CStr(m))
Do While W <= 9
If W = 9 Then
'i是整数部分,j是分子,m是分母
If Jug(i, j, m) Then G = G + 1: i, j, m
End If
j = j + 1
m = j * (N - i)
W = Len(CStr(i)) + Len(CStr(j)) + Len(CStr(m))
Loop
Next i
Print G
d = True
End Sub

'判断是否满足条件--ii是整数部分,ji是分子,mm是分母
Private Function Jug(ByVal ii As Long, ByVal jj As Long, ByVal mm As Long) As Boolean
Dim Lins As String


Dim d(1 To 9) As Integer
Dim i As Integer
Dim j As Integer
Dim T As Integer
Lins = CStr(ii) & CStr(jj) & CStr(mm)
For i = 1 To 9
d(i) = Val(Mid(Lins, i, 1))
Next i
For i = 1 To 8
For j = i + 1 To 9
If d(i) > d(j) Then
T = d(i)
d(i) = d(j)
d(j) = T
End If
Next j
Next i
Lins =
For i = 1 To 9
Lins = Lins & CStr(d(i))
Next i
If Lins =
Jug = True
Else
Jug = False
End If
End Function

2013年12月17日

斯坦福大学商学院-客户答谢会致辞


华中科技大学研究生招生信息-周记大全300字


高考状元杀死同学-五年级下册数学总结


同济大学录取分数线-乘车路线


长春专科-开学手抄报


大街招聘-发言材料


医学检验专业-模拟法庭心得体会


林肯大学-山西省招生考试信息网