Sub Main()
Dim Res, tRes(), N&, d As Variant
N = 10 'So dong, So cot
ReDim tRes(1 To N, 1 To N)
Call DuongCheo(tRes, N)
Res = NgauNhien(tRes, N)
Sheet1.UsedRange.Clear
If TypeName(Res) = "Variant()" Then
Res = ChuyenSo(Res, N, -1)
Sheet1.Range("B2").Resize(N, N) = Res
Sheet1.Range("B2").Resize(N, N).Borders.LineStyle = 1
Else
MsgBox ("Chua ohay xong")
End If
End Sub
Private Function NgauNhien(tRes, N)
Dim Res, Res2, Arr, colArr, tArr, blnArr() As Boolean, iVal, aCol, tRow, aRow
Dim m&, i&, j&, k&, q&, p&, tmp&
ReDim blnArr(1 To N)
ReDim Arr(1 To N)
tArr = Create_tArr(tRes, blnArr, N)
Randomize
ChoiTiep:
p = p + 1
If p = 100 Then Exit Function
Res = tRes
colArr = tArr
For i = 1 To N
tRow = blnArr
For j = 1 To N
If Len(tRes(i, j)) Then tRow(tRes(i, j)) = True
Next j
j = 0: q = 0
Do While j <= N
Res2 = Res: aRow = tRow: aCol = colArr
For j = 1 To N
If Len(Res2(i, j)) = 0 Then
Call CreateArr(Arr, aRow, k, N, aCol, j)
If k Then
tmp = Arr(Int((k * Rnd) + 1))
Res2(i, j) = tmp
aRow(tmp) = True
aCol(j)(tmp) = True
Else
q = q + 1
If q >= 500 Then GoTo ChoiTiep
Exit For
End If
End If
Next j
If j > N Then
colArr = aCol
Res = Res2
End If
Loop
Next i
NgauNhien = Res
End Function
Private Function Create_tArr(tRes, blnArr, N)
Dim tArr
ReDim tArr(1 To N)
For j = 1 To N
tArr(j) = blnArr
For i = 1 To N
If Len(tRes(i, j)) Then tArr(j)(tRes(i, j)) = True
Next i
Next j
Create_tArr = tArr
End Function
Private Sub CreateArr(Arr, aRow, k, N, aCol, j)
Dim i&
k = 0
For i = 1 To N
If aCol(j)(i) = False Then
If aRow(i) = False Then
k = k + 1
Arr(k) = i
End If
End If
Next i
End Sub
Private Sub DuongCheo(tRes, N)
Dim i&
For i = 1 To N
tRes(i, i) = i
Next i
End Sub
Private Function ChuyenSo(ByVal sArr, ByVal N, ByVal dVal)
Dim i&, j&, Res
ReDim Res(1 To N, 1 To N)
For i = 1 To N
For j = 1 To N
Res(i, j) = sArr(i, j) + dVal
Next j
Next i
ChuyenSo = Res
End Function