Đếm số chữ số 0 liên tiếp tận cùng của n!

Tram Ho

Đây là một bài tập khá cơ bản về tư duy lập trình. Có nhiều cách để giải nó tuy nhiên ở đây tôi chỉ đề cập đến phương pháp tối ưu nhất.

I) Số số không tận cùng là gì ?

Ở đây nó có nghĩa là bạn đang đi tìm số số 10 xuất hiện trong tích của số đó hay nói cách khác là tìm (2 . 5) trong tích của n!. Vậy một cách cơ bản thì bạn chỉ cần đếm số lượng số hai và số lượng số 5 rồi sau đó chọn số nhỏ hơn.

Tuy nhiên, có thể dễ dàng nhận thấy rằng số số 2 trong tích của n! luôn lớn hơn số số 5. Thật vậy, bởi trong khoảng từ 1 -> n có khoảng n/2 số 2 (bởi mọi số chẵn đều chứa 2 trong tích (chưa kể đến những số là lũy thừa của 2 như 4,8,..). Còn với số 5 thì chỉ những số có tận cùng là 0, 5 thì mới chứa 5 trong tích.

Vậy nên số số 5 trong tích của n! luôn nhỏ hơn số số 2 do đó chỉ cần tìm số lần xuất hiện của 5 trong tích của n!.

II) Giải quyết vấn đề đặt ra:

Đến đây bạn đã biết rằng chỉ cần đếm số số 5 trong tích của n!, lấy một ví dụ: 15! có 3 số 5 trong tích => có 3 số không tận cùng của n!.

Vậy đếm số số 5 đó như thế nào???

Như đã đề cập ở trên hay theo kiến thức đã học ở bậc tiểu học thì những số chia hết cho 5 (có 5 trong tích) thì đều tận cùng bởi các số 0 hoặc 5 mà những số chia hết cho 5 sẽ cách đều nhau 5 đơn vị:

Ta hoàn toàn có thể tính được số lượng số chia hết cho 5 trong khoảng từ 1 -> n bằng phép toán n/5. Phải chăng như thế là đủ??? Cùng đến với một ví dụ:

Vậy số không đó ở đâu???

Hành trình đi tìm số 0 bị thiếu:

alt

Trước hết ta cần phải hiểu rõ tại sao lại thiếu mất một giá trị:

Khi ta lấy n/5 chính là ta đang đếm các số chia hết cho 5. Tuy nhiên số chia hết cho 5 cũng có số this, số that cũng có các số chứa 2, 3, 4, … số 5 trong tích: 25, 50, 75, 125, 3125, … Nghĩa là đối với các số này ta không chỉ lấy được 1 số 5 mà còn có thể là 2, 3, 4 số. Do đó ta cần phải định nghĩa lại:

Vậy ta lại tiếp tục tìm các số chia hết cho 5. Giống như trên ta lại sử dụng công thức n/25. Cứ tiếp tục như vậy với 125, 625, các lũy thừa của 5.

Như vậy, một cách tổng quát, ta có:

n5+n52+…+n5kfrac{n}{5} + frac{n}{5^2} + … + frac{n}{5^k}5n+52n+...+5kn

Code trên C++:

Vậy tại sao lại cứ liên tục n/5, không giống với công thức:

n25=n55frac{n}{25} = frac{frac{n}{5}}{5}25n=55n nên chỉ cần làm như code là đươc.

Lời kết:

Cảm ơn vì đã xem

Chia sẻ bài viết ngay

Nguồn bài viết : Viblo