Các bác hướng em cách giải bài này theo python với ạ. Cảm ơn MN ạ
- Nhập 1 chuỗi S gồm toàn các chữ số và 1 số nguyên N. Hãy chỉ ra cách xóa đúng N kí tự ra khỏi S để S có giá trị lớn nhất.
Các bác hướng em cách giải bài này theo python với ạ. Cảm ơn MN ạ
- Nhập 1 chuỗi S gồm toàn các chữ số và 1 số nguyên N. Hãy chỉ ra cách xóa đúng N kí tự ra khỏi S để S có giá trị lớn nhất.
Xoá cực tiểu địa phương đầu tiên N lần
Là sao ạ ? E mới học nên gà lắm bác ạ :((
291 xóa 1 còn 29 xóa 2 còn 91 thì xóa 2 trước khi xóa 1, vậy sao xóa chữ số nhỏ nhất được
À, mình nhầm .
Ví dụ có string = ‘12093’ và số n = 2
Vậy phải xoá 2 số ở vị trí bất kỳ hay 2 số ở vị trí kế tiếp nhau ta?
@TaoLaoBidaoBanBanhBa Chắc là 2 số ở vị trí bất kì, đề bảo là xóa đúng N kí tự
chứ không bảo là xóa đúng N kí tự ở vị trị kế tiếp nhau
. Hình như kết quả là 293 thì phải.
xóa dần đần cực tiểu đầu tiên trong các chữ số là được :V Như noz1995 bảo là cực tiểu địa phương :V ko phải xóa chữ số nhỏ nhất :V
lặp lại N lần là xong :V
thuật toán thì lặp tìm cặp chữ số liền kề nhau đầu tiên sao cho d_{i} < d_{i+1}, nếu tìm thấy thì xóa chữ số ở vị trí thứ i, nếu ko thấy thì xóa ở vị trí cuối cùng. Lặp N lần :V
Tối ưu hơn thì đừng reset i=0 chạy lại từ đầu sau mỗi lần lặp mà chạy tiếp tục luôn vì trước đó d_i \geq d_{i+1} rồi khỏi cần lặp lại
À mà chắc phải lùi i đi 1 đơn vị :V vd 9876\textcolor{orange}67134 xóa 6 ở i=4 thành 9876\textcolor{orange}7134 lúc này i trỏ tới 7 là thiếu rồi :V :V Nhưng khi lùi thì phải ktra i=0 hay ko nữa mới -1 được :V Thôi reset i=0 luôn cho đỡ nhức đầu =]]
À nếu tìm d_{j-1} < d_j rồi xóa ở j-1 thì ko cần lùi j, chắc được =]
Mình không biết có cách chính thống hay giải thuật nào không, nhưng nếu chỉ là remove 2 (hoặc n) số ở vị trí nào cũng được, thì cũng không phức tạp lắm.
Cách làm của mình đơn giản là:
#1. Dùng loop để remove 1 số ở tất cả các vị trí, cho hết các kết quả vào list, rồi chọn số lớn nhất
#2. Dùng output của #1 và lặp lại n lần bước 1
#3. So sánh output của #2 với string gốc, để biết được n số cần remove là những số nào
Ví dụ bên dưới là mình làm tới bước #2
my_string = '92091'
my_number = 3
def find_max(string_s):
list_of_num = []
for j in range(len(list(string_s))):
list_TEMP = list(string_s).copy()
list_TEMP.pop(j)
list_of_num.append(int(''.join(list_TEMP)))
return str(max(list_of_num))
i = 0
while i < my_number:
i = i + 1
my_string = find_max(my_string)
print(my_string)
Output:
99
[Finished in 0.5s]
Bạn đã chạy thử đoạn code bên trên chưa?
à ra là chạy trâu xóa lần lượt tất cả à sorry đọc code chạy nhẩm thử thấy tưởng chỉ lấy max từ từ =]
duyệt trâu thì cần 3 dòng thôi =]
S = '38921'
N = 2
for _ in range(N):
S = max([c for i, c in enumerate(S) if i != j] for j in range(len(S)))
print(int(''.join(S)))
Cảm ơn bác nhé hehehe
Hay! Mình chưa thử bài toàn này, chỉ đọc qua lời giải của bạn thì thấy rất thú vị, nó giống như cách người ta tát ao bắt cá
Bạn học lớp mấy rồi?
Vâng,mình nghĩ cách này khá đơn giản và không phải loop nhiều (vì số lần loop bị giới hạn bởi lượng chữ số của con số đang xử lý). Nhưng mặt khác mình không chắc là nó thể hiện được tinh thần của bài tập này.
Giải thích hộ mình code này với ạ
[c for i, c in enumerate(S) if i != j]
là tạo mảng từ S bỏ 1 kí tự ở vị trí j ra, mà duyệt for j in range(len(S)
nữa thì nó tạo ra đúng len(S) mảng mỗi mảng thiếu 1 số ở vị trí thứ j, rồi lấy max của các mảng này thôi
vd: 38921
ra 5 mảng con là [8,9,2,1], [3,9,2,1], [3,8,2,1], [3,8,9,1], [3,8,9,2]
rồi lấy max trong 5 mảng này là [8,9,2,1]