楼主 kevinchengcw |
关于查找和判断单元格相连并且相加和等于25的解题思路分享
相信大家基本上都玩过扫雷游戏,游戏涉及到一个交集的问题,本问题的解题思路就借鉴了该方法,所不同的是我们是以中心单元格的交集数来判断,而不是四周。
我们以一个单元格为中心,其周围会有八个单元格的区域可能出现其他的单元格,如下图
红色是中心单元格,**Э赡艹鱿制渌行牡ピ竦姆段?/font 首先考虑,当五个单元格相连时,最少会有几个交集区,下图是交集最少的情况例子
或 或
也就是当两头的单元格与其他单元格只有一个交集,中间单元格与其他单元格只有两个交集时,于是我们得到了最少的单元格交集数,1+2+2+2+1=8,但是还不全对,并不是达到这个值就一定是全部紧邻的,还有下面的情况也满足数量,但并不是全部相连的
或
所以,除了要判断交集数量外,还要判断是否有孤立的一个或两个单元格,判断有一个孤立的单元格只需要判断五个单元格中是否有一个单元格与其他任何单元格都没有交集即可,判断两个单元格是否孤立在外则要判断是否存在两个相邻并且与其他单元格只有一个交集的情况。
思路有了,下面是看一下所面对的情况,题目中的情况如下图:
寻找单元格内相邻的五个数字单元格,且数值不同,相加之和等于25。 第一步:将单元格范围赋值给一个Range变量,从而可以用下标提取出相应的单元格。 第二步:因为是要找出相邻的五个单元格,所以我们设置五个变量,让第一个变量值范围从1到单元计数减4,即从第一个到倒数第五个,第二个变量从第一个变量加1到单元格计数减3,即永远是第一个变量的下一个,从而保证不重复,依此类推,设定好五个变量的范围及循环嵌套关系。 第三步:循环时每个变量做为下标,先判断对应单元格是否为空值,非空时是否与外层嵌套中的变量对应的单元格值相等,全部变量满足作为下标时对应的单元格不为空且各个单元格的值全不相等,则进入下面的核心判断过程。 第四步:首先判断五个单元格的交集区域个数,用单元格坐标加offset来判断在八个offset的单元地址是否与其他单元格相同,从而判断交集数。 情况1:当有任意一个单元格的交集数为0时则跳出循环,因为这表明这是一个孤立的单元格,未与其他单元格相邻,不合题意,跳过。 情况2:当一个单元格与其他单元格的交集数为1时,继续判断与他相交的单元格与其他单元格的交集数,如果也为1,则证明是两个孤立的单元格,不符合题意,跳过。 情况3:五个判断完后相加的总和大于8且未出现上述两种情况的组合,符合题意,予以标示记录。 第五步:程序加工润色,提升视觉效果。
综上,一个提速的方法是先建立一个非空值的单元格地址数组,则可省略五个变量循环判断一次的时间。 详见附件
- Sub test()
- Dim Rng, Uni As Range
- Dim A, B, C, D, E, F, G, H, I, J, K, L, M, N, P, Q As Integer
- Dim Ad As String
- Dim Arr
- tt = MsgBox("您是否要检测搜索到的结果?", vbYesNo)
- If tt = vbNo Then Application.ScreenUpdating = False
- Set Rng = Range("g5:k12")
- M = Rng.Cells.Count
- N = 0
- For A = 1 To M - 4
- If Rng(A) <> "" Then
- For B = A + 1 To M - 3
- If Rng(B) <> "" And Rng(B) <> Rng(A) Then
- For C = B + 1 To M - 2
- If Rng(C) <> "" And Rng(C) <> Rng(B) And Rng(C) <> Rng(A) Then
- For D = C + 1 To M - 1
- If Rng(D) <> "" And Rng(D) <> Rng(A) And Rng(D) <> Rng(B) And Rng(D) <> Rng(C) Then
- For E = D + 1 To M
- If Rng(E) <> "" And Rng(E) <> Rng(A) And Rng(E) <> Rng(B) And Rng(E) <> Rng(C) And Rng(E) <> Rng(D) Then
- If Rng(A).Value + Rng(B).Value + Rng(C).Value + Rng(D).Value + Rng(E).Value = 25 Then
- Arr = Array(Rng(A).Address, Rng(B).Address, Rng(C).Address, Rng(D).Address, Rng(E).Address)
- 'Debug.Print Rng(A).Address & " : " & Rng(B).Address & " : " & Rng(C).Address & " : " & Rng(D).Address & " : " & Rng(E).Address
- K = 0
- For G = 0 To 4
- J = 0
- For H = 0 To 4
- If H <> G Then
- Select Case Arr(H)
- Case Is = Range(Arr(G)).Offset(-1, -1).Address
- Ad = Arr(H)
- J = J + 1
- Case Is = Range(Arr(G)).Offset(-1, 0).Address
- Ad = Arr(H)
- J = J + 1
- Case Is = Range(Arr(G)).Offset(-1, 1).Address
- Ad = Arr(H)
- J = J + 1
- Case Is = Range(Arr(G)).Offset(0, -1).Address
- Ad = Arr(H)
- J = J + 1
- Case Is = Range(Arr(G)).Offset(0, -1).Address
- Ad = Arr(H)
- J = J + 1
- Case Is = Range(Arr(G)).Offset(1, -1).Address
- Ad = Arr(H)
- J = J + 1
- Case Is = Range(Arr(G)).Offset(1, 0).Address
- Ad = Arr(H)
- J = J + 1
- Case Is = Range(Arr(G)).Offset(1, 1).Address
- Ad = Arr(H)
- J = J + 1
- End Select
- End If
- Next H
- If J = 0 Then GoTo skip1
- If J = 1 Then
- Q = 0
- For L = 0 To 4
- P = 0
- If Arr(L) <> Ad Then
- Select Case Arr(L)
- Case Is = Range(Ad).Offset(-1, -1).Address
- P = P + 1
- Case Is = Range(Ad).Offset(-1, 0).Address
- P = P + 1
- Case Is = Range(Ad).Offset(-1, 1).Address
- P = P + 1
- Case Is = Range(Ad).Offset(0, -1).Address
- P = P + 1
- Case Is = Range(Ad).Offset(0, -1).Address
- P = P + 1
- Case Is = Range(Ad).Offset(1, -1).Address
- P = P + 1
- Case Is = Range(Ad).Offset(1, 0).Address
- P = P + 1
- Case Is = Range(Ad).Offset(1, 1).Address
- P = P + 1
- End Select
- End If
- Q = Q + P
- Next L
- If Q = 1 Then GoTo skip1
- End If
- K = K + J
- Next G
- If K < 8 Then GoTo skip1
- N = N + 1
- If tt = vbYes Then
- Rng(A).Interior.Color = vbRed
- Rng(B).Interior.Color = vbRed
- Rng(C).Interior.Color = vbRed
- Rng(D).Interior.Color = vbRed
- Rng(E).Interior.Color = vbRed
- ask = MsgBox("检测结果,是继续,否退出程序", vbYesNo)
- Rng(A).Interior.Color = xlNone
- Rng(B).Interior.Color = xlNone
- Rng(C).Interior.Color = xlNone
- Rng(D).Interior.Color = xlNone
- Rng(E).Interior.Color = xlNone
- If ask = vbNo Then Exit Sub
- End If
- End If
- End If
- skip1:
- Next E
- End If
- Next D
- End If
- Next C
- End If
- Next B
- End If
- Next A
- Application.ScreenUpdating = True
- MsgBox "共找到 " & N & " 种组合", vbOKOnly, ""
- End Sub
查找和判断单元格相邻并且相加和等于25.rar 关于查找和判断单元格相邻并且相加和等于25的解题思路分享.rar 查找和判断单元格相邻并且相加和等于25_07版.rar |