Bài toán giai thừa và chữ số 0

5 313 0
Bài toán giai thừa và chữ số 0

Đang tải... (xem toàn văn)

Thông tin tài liệu

Trở lại toán tìm chữ số tận khác n! Ngô Minh Đức Trong "Tối ưu tóan số nguyên tố" (THNT 10/2003), tác giả Đinh Hữu Công nêu thuật toán "Tìm chữ số tận khác n!" với n2, phân tích n!, ta có a2 > a5 (tức dấu = không xảy ra) hay a2 − a5>0 Do (n!)’ chia hết cho L(n!)=L(n!’) nhận giá trị {2;4;6;8} Mặt khác, ta có công thức: n!=n(n-1)! Kết hợp hai điều ta suy ra: L(n!)=L(L(n).L((n -1)!)) với n không chia hết cho Như biết giá trị L((5n)!) ta tính giá trị L((5n+j)!) với j=0,1,2,3,4 Các giá trị L(n!) xếp cột thành chuỗi chữ số sau: n: 01234 10 15 20 25 30 35 40 45 L(n!): 01264 22428 88682 88682 44846 44846 88682 22428 22428 66264 … (ta bỏ qua số giá trị đặc biệt 0!, 1! − xem L(0!)=0) Tuy nhiên giá trị L((5n)!) không thực rõ ràng Nếu ta tiếp tục xếp cột giá trị L((5n)!) ta thấy chúng lập thành chuỗi chữ số Điều cho phép ta nêu kết luận tương tự: cần biết giá trị L((25n)!) biết L((25n+5j)!) với j=0,1,2,3,4 (nghĩa giá trị L((25n+5j)!) phụ thuộc vào giá trị L((25n)!) Tiếp tục thế, xếp giá trị L((5kn)!) bảng sau: Ta rút kết luận (không thấy tác giả chứng minh): giá trị L((5kn+5k-1j)!) phụ thuộc vào giá trị L((5kn)!) với j=0,1,2,3,4 Nếu giá trị L((5kn)!) xác định giá trị L((5kn + 5k-1j)!) xác định Ví dụ: Ta có L((125.3)!)=L(375!)=2 L((125.3+25)!)=L(400!)=8 Thế L((125.8)!)=L(1000!)=2 nên L((125.8+25)!)=L(1025)! L((125.10)!=L(1250!)=2 nên L((125.10+25)!)=L(1275!) 8)… Tóm lại ta khẳng định L((125.k)!)=2 chắn L((125.k+25)!)phải chữ số thứ hai chuỗi 28488 (chữ số 8) Mặt khác, ta nhận thấy giá trị L((625n)!) giống với L(n!) Điều cho thấy L((5kn)!)=L((5k+4n)!) với n≠1 (không thấy tác giả chứng minh) Trên dòng ta thấy có chuỗi phân biệt gồm chữ số, chuỗi bắt đầu số {0,2,4,6,8} Ta cần tổng hợp tất chuỗi lại thành bảng để sử dụng Chúng ta rút bảng sau dùng để tính giá trị L((5kn +5k−1j)!) với j=0,1,2,3,4 biết giá trị L((5kn)!): Chẳng hạn biết L((125.2)!)=8 ta tính L((125.2+25.2)!)=6 cách nhìn vào hàng (2 mod 4)=2 (do 25=52), chuỗi bắt đầu chữ số (82622), vị trí j=2 Thuật toán tìm L(n!) Đổi n số 5, ta được: Dựa vào bảng trên, ta thấy biết L((dn5n)!) ta tính L((dn5n +dn-15n-1 )!) Tương tự biết L((dn5n +dn-15n-1 )!), ta tính L((dn5n +dn-15n-1 + dn25n-2)!), v.v cuối tính L(n!) Tuy nhiên phải tính L((dn5n)!), muốn ta hình dung: Do L((dn+15n+1)!)=0(một quy ước cho phù hợp với bảng � để ta xét chuỗi có chữ số 0) Ta dựa vào L((dn+15n+1)!)=0 dde^? L((dn5n)!) Ví dụ với n=1592: Bước 1: đổi n số 5, Bước 2: Xét dòng (=4 mod 4), chuỗi có chữ số đầu 0, tức 06264 Bước 3: chữ số n (cơ số 5) 2, L((2.54)!) =2, chữ số vị trí j=2 Bước 4: Xét dòng (=3 mod 4), chuỗi có chữ số 2, tức 26648 Bước 5: chữ số thứ hai n (cơ số 5) 2, L((2.54+2.53)!) =6, chữ số vị trí j=2 Bước 5: Xét dòng (=2 mod 4), chuỗi có chữ số 6, tức 64244 Bước 6: chữ số thứ ba n (cơ số 5) 3, L((2.54+2.53 +3.52)!)=4 số vị trí j=3 … Cuối ta có: L(1592!) = L((2.54+2.53 +3.52 + 3.5 + 2)!)=4 Chúng ta mô tả bảng cách xây dựng mảng Ă4,5,5) Trong số cho biết vị trí dòng (0,1,2,3); số thứ hai cho biết chữ số chuỗi (0,2,4,6,8); số thứ ba cho biết vị trí j (0,1,2,3,4) Nếu gọi dk chữ số thứ k hệ số n, ta mô tả thuật tóan ngắn gọn sau: Sn = Ăn mod 4, 0, dn) Sn-1 = Ăn-1 mod 4, sn, dn-1) … S1= A(1,s2, d1) S0= s1, d0) Cuối ta có S0 = L(n!) Chương trình: Dữ liệu: gồm số tự nhiên n đặt file NONZERO.INP Quy định: Số viết nhiều dòng (nếu qúa dài) vd: NONZERO.INP 549485904089340974897979878989793489787935789973493489789438957897578 478993476894845989897348 Kết qủa: in hình L(n!) Chương trình tính L((1000!)!) = thời gian chưa tới 0.5 giây Program Least_Significant_Non_Zero_Digit_of_f_n; (*=============KHAI=BAO=============*) Const InputFile=’NONZERO.INP’; Const Digits: array[’0’ ’9’] of byte=(0, 1, 2, 3, 4, 5, 6, 7, 8, 9); Table:array[0 3,0 4,0 4] Of Byte= (((0,6,2,6,4), (2,2,4,2,8), (4,4,8,4,6), (6,6,2,6,4), (8,8,6,8,2)), ((0,2,8,8,4), (2,4,6,6,8), (4,8,2,2,6), (6,2,8,8,4), (8,6,4,4,2)), ((0,4,2,4,4), (2,8,4,8,8), (4,6,8,6,6), (6,4,2,4,4), (8,2,6,2,2)), ((0,8,8,2,4), (2,6,6,4,8), (4,2,2,8,6), (6,8,8,2,4), (8,4,4,6,2))); Type BigInt= array[1 10000] of 9; Var A: BigInt; R5:BigInt; N, N5:Word; L: Byte; (*==========DOC=DU=LIEU===========*) Procedure Input; Var I:Word; F:Text; Ch:Char; B:BigInt; Begin Assign(F,InputFile); Reset(F); While Not EOF(F) Do Begin While not EOLN(F) Do Begin Read(F,Ch); N:=N+1; B[N]:=Digits[Ch]; End; Readln(F); End; Close(F); {Mang B chua cac chu so viet xuoi: vd so=1592, B=[1,5,9,2]} {Mang A chua cac chu so viet nguoc: vd so=1592, A=[2,9,5,1]} {Ta su dung mang A cho thuan tien ve sau} For I:=1 To N Do A[I]:=B[N-I+1]; If (N=1) And ((A[1]=0) Or (A[1]=1)) Then {0! hay 1!} Begin Write(1); Readln; Halt(1); End; End; (*=========DOI=SANG=CO=SO=5=========*) Procedure Radix5; Var I,J:Word; C:Byte; Begin C:=0; N5:=0; Repeat N5:=N5+1; R5[N5]:=A[N5] mod 5; {Thay vi chia ta nhan voi roi chia cho 10 bang cach bo di chu so tan cung} For I:=N5 To N Do Begin A[I]:=A[I]*2+C; C:=A[I] div 10; A[I]:=A[I] mod 10; End; If C=1 Then Begin N:=N+1; A[N]:=1; C:=0; End; J:=J+1; A[N5]:=0; Until N5=N; End; (*=========TIM=CHU=SO=TAN=CUNG=KHAC=0=CUA=N!=========*) Procedure Solve; Var S:Byte; I:Word; Begin S:=0; For I:=N5 DownTo Do S:=Table[(I-1) Mod 4,S div 2,R5[I]]; L:=S; End; (*=========CHUONG=TRINH=CHINH=========*) Begin Input; Radix5; Solve; Writeln(L); Readln; End ... chuỗi có chữ số đầu 0, tức 06 264 Bước 3: chữ số n (cơ số 5) 2, L((2.54)!) =2, chữ số vị trí j=2 Bước 4: Xét dòng (=3 mod 4), chuỗi có chữ số 2, tức 26648 Bước 5: chữ số thứ hai n (cơ số 5) 2,... dựng mảng Ă4,5,5) Trong số cho biết vị trí dòng (0, 1,2,3); số thứ hai cho biết chữ số chuỗi (0, 2,4,6,8); số thứ ba cho biết vị trí j (0, 1,2,3,4) Nếu gọi dk chữ số thứ k hệ số n, ta mô tả thuật tóan... số 5) 2, L((2.54+2.53)!) =6, chữ số vị trí j=2 Bước 5: Xét dòng (=2 mod 4), chuỗi có chữ số 6, tức 64244 Bước 6: chữ số thứ ba n (cơ số 5) 3, L((2.54+2.53 +3.52)!)=4 số vị trí j=3 … Cuối ta có:

Ngày đăng: 06/07/2017, 14:16

Từ khóa liên quan

Mục lục

  • Trở lại bài toán tìm chữ số tận cùng khác 0 của n!

Tài liệu cùng người dùng

Tài liệu liên quan