Hãy tìm giúp các số mà các chữ cái đang làm đại diện cho nó.
Xin vui lòng cho hỏi, đại diện ký tự đó là số nguyên hay số thực ạ?
Và có phải rằng khi đã là A thì các ký tự khác phải khác A đúng không? Và Len(A) = 1 hay nhiều hơn ạ?
Em hỏi lại:Hãy tìm giúp các số mà các chữ cái đang làm đại diện cho nó.
Dĩ nhiên phải tínhBạn làm theo phương pháp nào? Ngẫu nhiên hay có tính toán?
À quên, do F là số 0 bạn.Ủa tui thấy bác SA chia cho 5 con số lận mà bạn ABCDE / FGHIJ
Sub chay()
Dim M As String, k As Byte, i As Long, j As Long, x As Byte, d As Byte
k = 1
For i = 11106 To 98765
For j = 1234 To 10974
If i / j = 9 Then
'[D1] = i
M = Format(i, "00000") & Format(j, "00000")
For x = 2 To 10
If InStr(x, M, Mid(M, x - 1, 1)) = 0 Then
d = 1
Else
d = 0
Exit For
End If
Next
If d = 1 Then
Cells(k, "A") = i
Cells(k, "B") = j
k = k + 1
End If
End If
Next
Next
End Sub
Bạn tìm giúp tôi cặp số ấy trong 8 trường hợp có thương khác nhau từ 1 đến 8.
Còn 5 trường hợp nữa tôi chưa ghi raTo Learning_Excel : Cứ cho rằng có ký số 0 ở đầu số chia thì còn 2 đáp án nữa;
Nếu không kể các trường hợp này thì vẫn có thể tìm ra 3 nghiệm nữa đó các bạn.
Nhưng đừng mò chứ; BOX lập trình mà!
Rất cảm ơn các bạn đã quan tâm.
Từ 2 đến 8 thôi chứ nhỉ?
Tôi chạy code này thử nhưng tốc độ chậm quá nên không đủ kiên nhẫn đợi. Xin góp vui 1 đoạn code như sau.Những cặp như vầy có thoả đề không bác?
Và sau khi tối ưu 1 chút cho code thì nó thành ra như vầy!57429|06381
58239|06471
75249|08361
95742|10638
95823|10647
97524|10836
PHP:Sub chay() Dim M As String, k As Byte, i As Long, j As Long, x As Byte, d As Byte k = 1 For i = 11106 To 98765 For j = 1234 To 10974 If i / j = 9 Then '[D1] = i M = Format(i, "00000") & Format(j, "00000") For x = 2 To 10 If InStr(x, M, Mid(M, x - 1, 1)) = 0 Then d = 1 Else d = 0 Exit For End If Next If d = 1 Then Cells(k, "A") = i Cells(k, "B") = j k = k + 1 End If End If Next Next End Sub
Thân.
Sub test()
Dim iStart As Long
Dim iFinish As Long
Dim iBigNum As Long
Dim iSmallNum As Long
Dim iResult As Integer
Dim bOK As Boolean
Dim iCheck As Integer
Dim sTemp As String
iStart = 1234 * 9
iFinish = WorksheetFunction.Floor(98765, 9)
For iBigNum = iStart To iFinish Step 9
iSmallNum = iBigNum \ 9
sTemp = Format(iBigNum, "00000") & Format(iSmallNum, "00000")
bOK = True
For iCheck = 2 To 10
If InStr(iCheck, sTemp, Mid(sTemp, iCheck - 1, 1)) > 0 Then
bOK = False
Exit For
End If
Next
If bOK Then
iResult = iResult + 1
Cells(iResult, 1) = iBigNum
Cells(iResult, 2) = iSmallNum
End If
Next
End Sub
Fát huy chiến quả, ta sang tiếp bài 1.1, như sau
ABCDE & FGHI sẽ cho ta thương số trãi dài lần lượt từ 1 đến 8
Biết rằng 9 chữ cái này đại diện cho các số từ 1 đến 9 (không trùng lắp). Bạn tìm giúp tôi cặp số ấy trong 8 trường hợp có thương khác nhau từ 1 đến 8. (Vì 9 ta làm rồi, khà, khà,. . . !)
Cảm ơn các bạn đã quan tâm!
Sub thuonglt()
Dim i As Long, j As Long, x As Long, d As Byte, dl As String, M As String, iCol As Long
dl = "1-2-3-4-5-6-7-8"
Range("A1", Cells(65000, UBound(Split(dl, "-")) + 1)).ClearContents
For i = 0 To UBound(Split(dl, "-"))
Cells(1, i + 1) = Split(dl, "-")(i)
Next
For i = 1234 To 98765
Application.StatusBar = i & " " & WorksheetFunction.Round(((i - 1234) / 97531) * 100, 2) & "%"
For j = 0 To UBound(Split(kiem(i, dl), "-"))
If kiem(i, dl) = "" Then Exit For
iCol = Val(Split(kiem(i, dl), "-")(j))
M = Format(i, "00000") & Format(i / iCol, "00000")
For x = 2 To 10
If InStr(x, M, Mid(M, x - 1, 1)) = 0 Then
d = 1
Else
d = 0
Exit For
End If
Next
If d = 1 Then
Cells(65000, WorksheetFunction.Match(iCol, Range("A1", Cells(1, UBound(Split(dl, "-")) + 1)), 0)).End(xlUp).Offset(1) = i & "-" & i / iCol
Cells(65000, WorksheetFunction.Match(iCol, Range("A1", Cells(1, UBound(Split(dl, "-")) + 1)), 0)).End(xlUp).Select
End If
Next
Next
[A2].Select
End Sub
Function kiem(so As Long, dl As String)
Dim temp As String
For i = 1 To UBound(Split(dl, "-"))
If so Mod Val(Split(dl, "-")(i)) = 0 Then
temp = temp & Split(dl, "-")(i) & " "
End If
Next
kiem = Replace(Trim(temp), " ", "-")
End Function
Option Explicit
[B]Sub chay01()[/B]
Dim M As String, jJ As Byte, Ww As Long, Zz As Long, Ff As Byte, JF As Byte
Dim Timer_ As Double
jJ = 1: Timer_ = Timer
For Ww = 11106 To 98765
1 If Ww \ 9 = Ww / 9 Then
For Zz = 1234 To 10974
2 If Zz \ 9 = Zz / 9 Then
If Ww / Zz = 9 Then
[D1] = Ww
M = Format(Ww, "00000") & Format(Zz, "00000")
For Ff = 2 To 10
If InStr(Ff, M, Mid(M, Ff - 1, 1)) = 0 Then
JF = 1
Else
JF = 0: Exit For
End If
Next
If JF = 1 Then
Cells(jJ, "A") = Ww: Cells(jJ, "B") = Zz
jJ = jJ + 1
End If
End If
21 End If
Next
11 End If
Next
Cells(65500, "D").End(xlUp).Offset(1).Value = Timer - Timer_
[B]End Sub[/B]
Đâu có gì ghê gớm đâu. Bạn chỉ cần phân tích đề 1 chút thì sẽ có hướng làm thôi. Mấy con số 1234 hay 98765 kia thì khoan vội quan tâm đã. Bạn thấy 1 số có 5 chữ số khác nhau thì cứ xem đó như 1 số có 5 chữ số thôi vậy nó phải nằm trong [1000,99999] đúng không?hic. em đọc mãi mà vẫn chưa hiểu rõ về code này. bác Po_Pikachu giải thích một ít đi. Cho bọn em còn học hỏi và nâng cao thuật toán tý.
cảm ơn bác nhìu nhìu
For i = 1000 To 99999
For j = 1000 To 99999
If i / j = 9 Then
M = Format(i, "00000") & Format(j, "00000")
For x = 2 To 10
If InStr(x, M, Mid(M, x - 1, 1)) = 0 Then
???
Else
???
End If
Next
If ??? Then
Cells(k, "A") = i
Cells(k, "B") = j
End If
End If
Next
Next
Thấy thời gian rút đáng kể; Đó là nhờ các dòng lệnh được đánh số thêm vào:
Mã:Option Explicit [B]Sub chay01()[/B] Dim M As String, jJ As Byte, Ww As Long, Zz As Long, Ff As Byte, JF As Byte Dim Timer_ As Double jJ = 1: Timer_ = Timer For Ww = 11106 To 98765 1 If Ww \ 9 = Ww / 9 Then For Zz = 1234 To 10974 2 If Zz \ 9 = Zz / 9 Then If Ww / Zz = 9 Then [D1] = Ww M = Format(Ww, "00000") & Format(Zz, "00000") For Ff = 2 To 10 If InStr(Ff, M, Mid(M, Ff - 1, 1)) = 0 Then JF = 1 Else JF = 0: Exit For End If Next If JF = 1 Then Cells(jJ, "A") = Ww: Cells(jJ, "B") = Zz jJ = jJ + 1 End If End If 21 End If Next 11 End If Next Cells(65500, "D").End(xlUp).Offset(1).Value = Timer - Timer_ [B]End Sub[/B]
Thời gian theo máy của mình rút từ 77.891 gy còn 9.359 gy Nhờ vào tính chia hết của tử số cũng như mẫu số
Sub Thuong9()
Dim M As String, k As Byte, i As Long, j As Long, x As Byte, d As Byte
Dim Timer_ As Double
k = 1: Timer_ = Timer
For i = 1234 To 98765
If i Mod 9 = 0 Then
M = Format(i, "00000") & Format(i / 9, "00000")
d = 0
For x = 2 To 10
If InStr(x, M, Mid(M, x - 1, 1)) = 0 Then
d = d + 1
Else
Exit For
End If
Next
If d = 9 Then
Cells(k, "A") = i
Cells(k, "B") = i / 9
k = k + 1
End If
End If
Next
Range("E1") = Timer - Timer_
MsgBox (Timer - Timer_)
End Sub
PHP:Sub thuonglt() Dim i As Long, j As Long, x As Long, d As Byte, dl As String, M As String, iCol As Long, test As String Dim Timer_ As Double dl = "1-2-3-4-5-6-7-8": Timer_ = Timer Range("A1", Cells(65000, UBound(Split(dl, "-")) + 1)).ClearContents For i = 0 To UBound(Split(dl, "-")) Cells(1, i + 1) = Split(dl, "-")(i) Next For i = 1234 To 98765 test = kiem(i, dl) For j = 0 To UBound(Split(test, "-")) If test = "" Then Exit For iCol = Val(Split(test, "-")(j)) M = Format(i, "00000") & Format(i / iCol, "00000") For x = 2 To 10 If InStr(x, M, Mid(M, x - 1, 1)) = 0 Then d = 1 Else d = 0 Exit For End If Next If d = 1 Then Cells(65000, WorksheetFunction.Match(iCol, Range("A1", Cells(1, UBound(Split(dl, "-")) + 1)), 0)).End(xlUp).Offset(1) = i & "-" & i / iCol End If Next Next [A2].Select MsgBox (Timer - Timer_) End Sub
PHP:Function kiem(so As Long, dl As String) Dim temp As String For i = 1 To UBound(Split(dl, "-")) If so Mod Val(Split(dl, "-")(i)) = 0 Then temp = temp & Split(dl, "-")(i) & " " End If Next kiem = Replace(Trim(temp), " ", "-") End Function
Sub Main(NumLength As Long, qt As Long)
Dim i As Long, j As Long, Tmp As String, Arr()
If NumLength > 5 Then Exit Sub
i = 10 ^ (NumLength - 1)
Do
Tmp = i & (i * qt)
If CheckUnique(Tmp) Then
ReDim Preserve Arr(j)
Arr(j) = i * qt & " = " & i & " * " & qt
j = j + 1
End If
i = i + 1
Loop Until i * qt > 10 ^ NumLength - 1
If j Then MsgBox Join(Arr, vbLf)
End Sub
Function CheckUnique(Num As String) As Boolean
Dim i As Long, Check As Boolean
Do
Check = (Len(Num) - Len(Replace(Num, i, "")) > 1)
i = i + 1
Loop Until Check Or i = 10
CheckUnique = Not Check
End Function
Sub Test()
Main 5, 9
End Sub
F=0 cũng là nghiệm chớ anh?Main 5, 9 có nghĩa là tìm các cặp số có độ dài chuổi = 5, có thưong số của phép chia giửa 2 số = 9
Thử nghiệm này cho ra 3 nghiệm
Đã gọi là số có 5 chữ số thì không có cái vụ số 0 nằm ở đầu nha!
Nếu F = 0 bạn gọi số chia là số có mấy chữ số?F=0 cũng là nghiệm chớ anh?
Sub Main(NumLength As Long, qt As Long)
Dim i As Long, j As Long, Tmp As String, Arr(60000, 1)
If NumLength > 5 Then Exit Sub
i = WorksheetFunction.RoundUp((10 ^ (NumLength - 1) / qt), 0)
Do
Tmp = i * qt & Format(i, String(NumLength, "0"))
If CheckUnique(Tmp) Then
Arr(j, 0) = i * qt
Arr(j, 1) = i
j = j + 1
End If
i = i + 1 - (((i + 1) Mod 10) = 0)
Loop Until i * qt > 10 ^ NumLength - 1
If j Then Range("A1:B1").Resize(j) = Arr
End Sub
Function CheckUnique(Num As String) As Boolean
Dim i As Long, Check As Boolean
Do
Check = (Len(Num) - Len(Replace(Num, i, "")) > 1)
i = i + 1
Loop Until Check Or i = 10
CheckUnique = Not Check
End Function
Sub Test()
Main 5, 9
End Sub
Bài toán tổng quát thì khỏi cần xét mấy vụ này!Các cặp số đó có những tính chất sau:
Để có kết quả là 9 thì cả hai số sẽ fải chia hết cho 9;
Nếu thương của cặp số là số chẵn thì số bị chia fải là số chẵn;
Nếu thương là lẽ, thì hai số cũng fải là lẽ.
Ta đưa các tính chất này vô, chắc sẽ giảm hao fí thời gian cho máy!
Chuổi "123456789" qua phép hoán vị ta được 362880 phần tử ---> Cái này em có thể tìm được!Cho 1 dãy số gồm 9 số khác nhau hoàn toàn & không có số không (ABCDEFGHI)
Đem số này chia cho số n sẽ fải nhận được 1 số như vậy, chỉ đảo vị trí giữa chúng
Hãy tìm các số ấy, khi n= 2, 4, 5, 7, 8
Dim n As Long, Arr(1 To 362880, 1 To 1)
Sub GetString()
Dim Num As String
Num = "123456789"
n = 1
GetPermu "", Num
Range("A1").Resize(n - 1) = Arr
End Sub
Sub GetPermu(x As String, y As String)
Dim i As Long, j As Long
j = Len(y)
If j < 2 Then
Arr(n, 1) = x & y
n = n + 1
Else
For i = 1 To j
GetPermu x & Mid(y, i, 1), Left(y, i - 1) & Right(y, j - i)
Next
End If
End Sub
Hay quá, cám ơn ndu, đang tìm cách tạo tổ hợp chập.Chuổi "123456789" qua phép hoán vị ta được 362880 phần tử ---> Cái này em có thể tìm được!
Tuy nhiên để tìm số thỏa mản yêu cầu mà sư phụ đưa ở trên thì... em chẳng tìm thấy số nào cả
PHP:Dim n As Long, Arr(1 To 362880, 1 To 1)
PHP:Sub GetString() Dim Num As String Num = "123456789" n = 1 GetPermu "", Num Range("A1").Resize(n - 1) = Arr End Sub
Code trên liệt kê tất cả các phần tử qua phép hoán vị ---> Các bạn tìm thử xem trong số đó có cái nào phù hợp yêu cầu không? (tôi bó tay)PHP:Sub GetPermu(x As String, y As String) Dim i As Long, j As Long j = Len(y) If j < 2 Then Arr(n, 1) = x & y n = n + 1 Else For i = 1 To j GetPermu x & Mid(y, i, 1), Left(y, i - 1) & Right(y, j - i) Next End If End Sub
Dùng Excel 2007 nha!
Với N=8Chuổi "123456789" qua phép hoán vị ta được 362880 phần tử ---> Cái này em có thể tìm được!
Tuy nhiên để tìm số thỏa mản yêu cầu mà sư phụ đưa ở trên thì... em chẳng tìm thấy số nào cả
PHP:Dim n As Long, Arr(1 To 362880, 1 To 1)
PHP:Sub GetString() Dim Num As String Num = "123456789" n = 1 GetPermu "", Num Range("A1").Resize(n - 1) = Arr End Sub
Code trên liệt kê tất cả các phần tử qua phép hoán vị ---> Các bạn tìm thử xem trong số đó có cái nào phù hợp yêu cầu không? (tôi bó tay)PHP:Sub GetPermu(x As String, y As String) Dim i As Long, j As Long j = Len(y) If j < 2 Then Arr(n, 1) = x & y n = n + 1 Else For i = 1 To j GetPermu x & Mid(y, i, 1), Left(y, i - 1) & Right(y, j - i) Next End If End Sub
Dùng Excel 2007 nha!
For Jj = 987654328 To 987654312 Step -8
. . . . .
Next Jj
Giải thuật này tôi đã áp dụng cho bài số #17, nhưng ở đây có mấy chỗ tôi thấy chưa hợp lý lắm.Thực ra bài toán đó cần biện luận trước, như sau:
Số nhỏ nhất trong đám là 123456789 (Min) & số lớn nhất không thể khác 987654321 (Max)
Giải trường hợp N=8:
Số lớn nhất có thể để thỏa điều kiện nhân với 8 bé hơn Max sẽ là Int(Max/8)+1. Bằng trang tính excel ta biết số đó là 123456791. Vậy tà từ Min đến số này có hơn 100 số chứ mấy!
Nhưng theo mình, cách giải sẽ ngược lại:
Ta fải tìm số lớn hơn Max gần nhất chia hết cho 8, đó là 987654328 (=FLOOR(987654321,8) + 8)
Tiếp đến ta tìm số nhỏ nhất để làm số bị nhân; Số đó sẽ là =FLOOR(123456789*8,8) :=987654312
Ô là là, vòng lặp của chúng ta giảm đáng kể rồi còn gì!
Nhưng chưa hết; Nếu ta biết rằng chỉ những con số chia hết cho 8 mới là đáp án mà thôi
Vậy là vòng lặp ta có dạng
PHP:For Jj = 987654328 To 987654312 Step -8 . . . . . Next Jj
Mình cho rằng đến giờ, cách này là tiết kiệm thời gian nhất.
Xin ý kiến các bạn xa gần.
Đúng là em bị mắc lừaÀ ha, NDU dính mẹo lão già rồi
Cái từ "đảo' ở đây em hiểu là: 123 sau khi "đảo" sẽ thành 321... Ai ngờ... chỉ đảo vị trí giữa chúng...
Dim n As Long, Arr(1 To 362880, 1 To 2) As Long
Sub Test()
Dim Num As String, qt As Long, TG As Double
TG = Timer
Range("A:B").ClearContents
Num = "123456789": qt = Range("G1").Value
n = 1
Main "", Num, qt
If n > 1 Then Range("A1").Resize(n - 1, 2).Value = Arr
MsgBox Timer - TG
End Sub
Sub Main(x As String, y As String, qt As Long)
Dim i As Long, j As Long, Tmp
j = Len(y)
If j < 2 Then
Tmp = x & y
If InStr(Tmp * qt, "0") = 0 Then
If CheckUnique(Tmp * qt) Then
Arr(n, 1) = Tmp
Arr(n, 2) = Tmp * qt
n = n + 1
End If
End If
Else
For i = 1 To j
Main x & Mid(y, i, 1), Left(y, i - 1) & Right(y, j - i), qt
Next
End If
End Sub
Function CheckUnique(Num As String) As Boolean
Dim i As Long, Check As Boolean
Do
Check = (Len(Num) - Len(Replace(Num, i, "")) > 1)
i = i + 1
Loop Until Check Or i = 10
CheckUnique = Not Check
End Function
Dim n As Long, Arr(1 To 362880, 1 To 2) As Long, ChkTotal As Long
Sub Test()
Dim Num As String, qt As Long, TG As Double
TG = Timer
Range("A:B").ClearContents
Erase Arr
Num = "123456789": qt = Range("G1").Value
n = 1: ChkTotal = WorksheetFunction.Fact(Len(Num)) / qt
Main "", Num, qt
If n > 1 Then Range("A1").Resize(n - 1, 2).Value = Arr
MsgBox Timer - TG
End Sub
Sub Main(x As String, y As String, qt As Long)
Dim i As Long, j As Long, Tmp
j = Len(y)
If ChkTotal = 0 Then Exit Sub
If j < 2 Then
ChkTotal = ChkTotal - 1
Tmp = x & y
If InStr(Tmp * qt, "0") = 0 Then
If CheckUnique(Tmp * qt) Then
Arr(n, 1) = Tmp
Arr(n, 2) = Tmp * qt
n = n + 1
End If
End If
Else
For i = 1 To j
Main x & Mid(y, i, 1), Left(y, i - 1) & Right(y, j - i), qt
Next
End If
End Sub