Giải trí với "ô vuông ma quái" trong excel (1 người xem)

Liên hệ QC

Người dùng đang xem chủ đề này

Em hỏi ngoài lề 1 chút: Cái MA PHƯƠNG này dùng làm gì trong THỰC TẾ vậy sư phụ?
Có ứng dụng thì mới "hứng thú" nghiên cứu
Chả có ứng dụng gì sất. Nó chỉ là nghiên kíu của mấy tay rảnh rỗi hồi mấy thế kỷ trước lận. (Vì vậy mới để nguyên trong box thư giãn).
Còn mình thì muốn tìm 1 giải thuật cho bất kỳ 1 bài toán nào, nếu có khả năng. Vận động đầu óc thì mai mốt già đỡ bị ai zơ me.
 
Cách tạo ma phương mà mình học từ lớp 5 là thế này:

- Viết các số thứ tự theo đường chéo
- dời các số nằm ngoài vào trong theo hướng mũi tên

attachment.php


Rõ ràng là sau khi xoay, hoặc lật, vị trí bắt đầu sẽ thay đổi.

Đang viết code để tạo ma phương có bậc lẻ bất kỳ.

Tóm lại là, nếu là ma phương lẻ, ắt có phần tử quay, cứ giá trị Tổng chia cho cấp của Ma trận là ra giá trị phần tử quay (trung gian). các phần tử khác cũng có quy tắc tính toán cả.

Với bài toán ma trận, có nghiệm hay không thì cứ giải bài toán bằng phương pháp đơn hình là ra được. Mà em thấy mấy bác yêu toán học thì khoái chứng minh chứ em thì chịu!

quote_icon.png
Nguyên văn bởi ndu96081631
Em hỏi ngoài lề 1 chút: Cái MA PHƯƠNG này dùng làm gì trong THỰC TẾ vậy sư phụ?
Có ứng dụng thì mới "hứng thú" nghiên cứu



Chả có ứng dụng gì sất. Nó chỉ là nghiên kíu của mấy tay rảnh rỗi hồi mấy thế kỷ trước lận. (Vì vậy mới để nguyên trong box thư giãn).
Còn mình thì muốn tìm 1 giải thuật cho bất kỳ 1 bài toán nào, nếu có khả năng. Vận động đầu óc thì mai mốt già đỡ bị ai zơ me.

Ứng dụng đầy ra đấy các bác ạh, nếu không toán học "chết" lâu rồi; các bác xem có nơi nào là không cần đến toán học? Kinh tế, Văn hoá, chính trị, xây dựng, hàng không, vũ trụ,.... chỉ có mình là không ứng dụng tới thôi, hihi!
 
Lần chỉnh sửa cuối:
Còn mình thì muốn tìm 1 giải thuật cho bất kỳ 1 bài toán nào, nếu có khả năng. Vận động đầu óc thì mai mốt già đỡ bị ai zơ me.
Ẹc... Ẹc... sư phụ ơi,trên GPE này còn cả mấy trăm bài Excel chưa giải... cho sư phụ tha hồ vận động đầu óc
Hổi xưa em đã từng biết qua bài toán này, có điều chẳng thấy ứng dụng quái gì nên cũng.. cóc thèm để ý
---------------------------------
Ứng dụng đầy ra đấy các bác ạh, nếu không toán học "chết" lâu rồi; các bác xem có nơi nào là không cần đến toán học? Kinh tế, Văn hoá, chính trị, xây dựng, hàng không, vũ trụ,.... chỉ có mình là không ứng dụng tới thôi, hihi!
Toán học là món mà tôi "mặn" nhất, nhưng ý tôi nói là ỨNG DỤNG THỰC TẾ cơ... để "chơi" thì nói làm gì (chẳng trách gì sư phụ cho nó vào box THƯ GIÃN)
 
Lần chỉnh sửa cuối:
Từ 5 đến 29 cũng được anh à, số bắt đầu từ bao nhiêu cũng được, và các số tăng dần theo cấp số cộng ví dụ có thể là 2, 4, 6, 8, .....
Cái này thì lại là phát triển cực kỳ đơn giản của ma phương mà bác. Bác điền từ 5-29 thì cũng như điền từ 1-25 rồi cộng thêm 4 vào mỗi ô mà. Còn 2,4,6,8,.. thì là nhân 2 với mỗi ô của ma phương thôi.
@Ptm: Cách giải của bác là hoàn toàn đúng và là cách đơn giản nhất rồi:D
@ndu96......: Về ma phương thì không có nhiều ứng dụng lắm, em cũng tình cờ có một dịp tìm hiểu về nó, và em thấy rất bất ngờ vì cách giải của nó hết sức đơn giản. Và em nghiệm ra một điều là tất cả những vấn đề khó khăn đều có thể giải quyết được bằng những cách hết sức đơn giản:D
 
Ma phương bậc lẻ thì thuật toán tương đối đơn giản và dễ nhớ, có thể đặt bút để điền luôn vào đc. Tôi mô phỏng thử thuật toán để đưa lên worksheet của excel như sau
Mã:
Sub MaPhuong(N As Integer)
    Dim arr() As Integer
    ReDim arr(0 To N - 1, 0 To N - 1)
    Dim iValue As Integer
    Dim iRow As Integer
    Dim iCol As Integer
    iRow = 0
    iCol = N \ 2
    For iValue = 1 To N ^ 2
        arr(iRow, iCol) = iValue
        If (arr((iRow - 1 + N) Mod N, (iCol + 1) Mod N) = 0) Then
            iRow = (iRow - 1 + N) Mod N
            iCol = (iCol + 1) Mod N
        Else
            iRow = (iRow + 1) Mod N
        End If
    Next
    Range("A1").Resize(N, N) = arr
End Sub
Thuật toán về cơ bản là giống nhau, tùy thuộc vào vị trí xuất phát mà thôi. Còn việc các con số không phải bắt đầu từ 1 hoặc không liên tục thì đơn giản là cộng hoặc nhân vào mỗi phần tử của ma phương 1 số thì sẽ có ngay thôi.
 
Hic, xem code của Rollover, vẫn là bài học cũ về sử dụng biến mảng, mà vẫn thấy mới. Xem xong, xé giấy nháp, bẻ gãy viết, đập đầu tự tử vào gối luôn.
 
Ma phương bậc lẻ thì thuật toán tương đối đơn giản và dễ nhớ, có thể đặt bút để điền luôn vào đc. Tôi mô phỏng thử thuật toán để đưa lên worksheet của excel như sau
Mã:
Sub MaPhuong(N As Integer)
    Dim arr() As Integer
    ReDim arr(0 To N - 1, 0 To N - 1)
    Dim iValue As Integer
    Dim iRow As Integer
    Dim iCol As Integer
    iRow = 0
    iCol = N \ 2
    For iValue = 1 To N ^ 2
        arr(iRow, iCol) = iValue
        If (arr((iRow - 1 + N) Mod N, (iCol + 1) Mod N) = 0) Then
            iRow = (iRow - 1 + N) Mod N
            iCol = (iCol + 1) Mod N
        Else
            iRow = (iRow + 1) Mod N
        End If
    Next
    Range("A1").Resize(N, N) = arr
End Sub
Khi tôi gán N = 4 thì các chiều ngang không bằng nhau. Bạn test lại thử.
 
Tham gia một code ma phương bậc lẻ

Tôi xin tham gia một code cho ma phương bậc lẻ.
Không mảng, không vòng lặp for (cho nên tốc độ chắc hẳn là nhanh).
Nhập số n vào ô A1 và chạy code.
Mời các bạn thử.
Option Explicit
Dim n As Long
Sub MaPhuongLe()
n = WorksheetFunction.Max([A1] + [A1] Mod 2 - 1, 3)
Cells.ClearContents
[A1] = n
[A3] = -n \ 2 - 1
[B3] = n * (n \ 2)
[C1] = -n \ 2 + 1
[C2] = n * (n \ 2 + 1) + 1
[C3] = "=A3+$A$1+1"
[C3].Copy Destination:=Range([C3], Cells(3, 2 + n))
[C3] = "=C1+$A$1-1"
[C3].Copy Destination:=Range([C3], Cells(2 + n, 3))
[D4] = "=MOD(C3+$A$1-1,$A$1*$A$1)+1"
[D4].Copy Destination:=Range([D4], Cells(2 + n, 2 + n))
Range([C3], Cells(2 + n, 2 + n)).Copy
[C3].PasteSpecial Paste:=xlPasteValues
[C1].ClearContents
[C2].ClearContents
[A3].ClearContents
[B3].ClearContents
End Sub
 
N=21
Code của RollOver: 0.015625 giây
Code của lypt: 0.0625 giây, gấp 4 lần

Biến mảng bao giờ cũng nhanh hơn, kể cả khi dùng vòng lặp. Thế nên tôi mới xé giấy nháp, bẻ viết, ...
 
ptm có thể thử test giúp tôi với số N khá lớn?
 
N|RollOver|Lypt|Tỷ lệ
21​
|
0,015625​
|
0,0625​
|4,000000
51​
|
0,078125​
|
0,140625​
|1,800000
151​
|
0,09375​
|
0,25​
|2,6666667
255​
|
0,21875​
|
0,53125​
|2,4285715
1.001​
|
3,515625​
|
39,421875​
|11,213333
2.001​
|
13,796875​
|
607,5625​
|44,03524
 
Lần chỉnh sửa cuối:
Biến mảng quả nhiên lợi hại

Tôi không ngờ biến mảng lại lợi hại thế, đến nay mới biết,
đúng là học hoài không hết, phải học mãi không ngừng.
Bắt chước code của rollover, tôi thử viết lại code của mình bằng cách sử dụng biến mảng thì tốc độ vẫn không so được với rollover, nhưng so với chính mình thì đã nhanh hơn hẳn.
Cám ơn các bạn, rollover, ptm, và GPE.
Sub MaPhuong()
N = WorksheetFunction.Max([A1] + [A1] Mod 2 - 1, 3)
Cells.ClearContents
[A1] = N
ReDim arr(0 To N - 1, 0 To N - 1)
arr(0, 0) = N - N \ 2
arr(0, 1) = N * (N \ 2) + N + 1
arr(1, 0) = N * (N \ 2 + 2)
For j = 2 To N - 1
arr(0, j) = arr(0, j - 2) + N + 1
Next j
For i = 2 To N - 1
arr(i, 0) = arr(i - 2, 0) + N - 1
Next i
For i = 1 To N - 1
For j = 1 To N - 1
arr(i, j) = (arr(i - 1, j - 1) - 1 + N) Mod N ^ 2 + 1
Next j, i
[C3].Resize(N, N) = arr
[C3].Resize(N, N).Select
End Sub
 
Nhờ cậu bạn chứng minh hộ bài toán với ma trận vuông cấp N với phương pháp đơn hình, thoả mãn điều kiện tổng các các cạnh, các cột, các đường chéo chính bằng nhau: Lấy random N là chẵn thì vô nghiệm. Tuy nhiên, chứng minh trên một tập hợp M các ma trận cấp N (chẵn) không có ma phương cấp N thì bó tay hoặc tìm ra nghiệm trong tập hợp M đó cũng bó tay luôn (Chờ chứng minh cái đã ...).

Em chỉ thấy quy tắc này: với ma phương (tạm thời coi luôn nó là ma trận bậc lẻ, có các tổng ngang, dọc, đường chéo chính bằng nhau) thì ngoài các quy tắc của các bác, em nhận thấy là: Phần tử quay (trung gian) = Tổng cần tìm / cấp ma trận (N), Tổng các đường chéo phụ luôn là một số chẵn. Đấy là em cảm thấy thế, bác nào dùng toán học chứng minh được không ạh?

Em thấy định nghĩa của các bác nói là tổng các đường chéo cũng bằng tổng các hàng ngang, cột dọc,... em có thấy thế đâu, em chỉ thấy đường chéo chính mới có tổng bằng thôi! Ma phương luôn tồn tại một vectơ cơ sở để tìm ra ma phương nghịch đảo!
 
Nhân đây xin gửi mọi người code thể hiện thuật toán cho ma phương chẵn, so với ma phương lẻ thì thuật toán phức tạp hơn chút.
Mã:
Sub MaPhuong(N As Integer)
    Const PntMir = "P"
    Const VerMir = "V"
    Const HorMir = "H"
    Const IgnMir = "I"

    Dim iRow As Integer
    Dim iCol As Integer
    
    Dim arr() As Integer
    ReDim arr(1 To N, 1 To N)
    For iRow = 1 To N
        For iCol = 1 To N
            arr(iRow, iCol) = (iRow - 1) * N + iCol
        Next
    Next
    
    Dim iRowProc As Integer
    iRowProc = N \ 2
    Dim sKey As String
    sKey = String(iRowProc \ 2, PntMir) & IIf(iRowProc Mod 2 = 1, VerMir & HorMir, "")
    sKey = sKey & String(iRowProc - Len(sKey), IgnMir)
    
    For iRow = 1 To iRowProc
        For iCol = 1 To iRowProc
            Select Case Mid(sKey, iCol, 1)
                Case PntMir:
                    Swap arr(iRow, iCol), arr(N - iRow + 1, N - iCol + 1)
                    Swap arr(iRow, N - iCol + 1), arr(N - iRow + 1, iCol)
                Case VerMir:
                    Swap arr(iRow, iCol), arr(N - iRow + 1, iCol)
                Case HorMir:
                    Swap arr(iRow, iCol), arr(iRow, N - iCol + 1)
            End Select
        Next
        sKey = Right(sKey, 1) & Left(sKey, Len(sKey) - 1)
    Next
    
    Range("A1").Resize(N, N) = arr
End Sub

Sub Swap(ByRef iNum1 As Integer, ByRef iNum2 As Integer)
    Dim iTemp As Integer
    iTemp = iNum1
    iNum1 = iNum2
    iNum2 = iTemp
End Sub
 
Cũng xin bám theo bạn rollover một code ma phương chẵn; thuật toán có vẻ cũng giống!
Option Explicit
Dim N As Long
Dim i As Long
Dim j As Long
Dim c As Long
Dim arr() As Long
Dim temp As Long
Sub MaPhuongChan()
N = WorksheetFunction.Max([A1] + [A1] Mod 2, 4)
Cells.ClearContents
[A1] = N
ReDim arr(1 To N, 1 To N)
For i = 1 To N
For j = 1 To N
arr(i, j) = (i - 1) * N + j
Next j, i
For i = 1 To N / 2
If N Mod 4 = 2 Then
c = (i + N - 2) Mod (N / 2) + 1
temp = arr(i, c)
arr(i, c) = arr(i, N + 1 - c)
arr(i, N + 1 - c) = temp
c = (i + N - 3) Mod (N / 2) + 1
temp = arr(i, c)
arr(i, c) = arr(N + 1 - i, c)
arr(N + 1 - i, c) = temp
End If
For j = 0 To N \ 4 - 1
c = (i + j - 1) Mod (N / 2) + 1
temp = arr(i, c)
arr(i, c) = arr(N + 1 - i, N + 1 - c)
arr(N + 1 - i, N + 1 - c) = temp
temp = arr(i, N + 1 - c)
arr(i, N + 1 - c) = arr(N + 1 - i, c)
arr(N + 1 - i, c) = temp
Next j, i
[B2].Resize(N, N) = arr
[B2].Resize(N, N).Select
End Sub
 
Oah oah! Choáng! Bạn em vừa chứng minh vô nghiệm các bác đã có code rồi! hihi! Cảm ơn các bác nhiều lắm ạh! Em lại biết thêm được một thứ! hihi!

Thân mến!
 
Web KT

Bài viết mới nhất

Back
Top Bottom