Chuyên đề các phép tính với số lớn trong ngôn ngữ lập trình pascal
Bạn đang xem nội dung tài liệu Chuyên đề các phép tính với số lớn trong ngôn ngữ lập trình pascal, để tải tài liệu về máy bạn click vào nút DOWNLOAD ở trên
Chuyên đề Các phép tính với số lớn trong NNLT Pascal. ( VVSửu., GV Trường THPT chuyên HN-AMSTERDAM) Đặt vấn đề. Do hạn chế về bộ nhớ, nên các phép toán cộng, trừ, nhân, chia trong NNLT pascal chỉ thực hiện được đối với các số nhỏ. Trong lúc đó nhiều bài toán cần thực hiện phép toán với hàng trăm, thậm chí hàng ngàn chữ số. Chúng ta sẽ sử dụng một vài cấu trúc dữ liệu như xâu, mảng và các thuật toán đã học từ thời THCS để thực hiện yêu cầu tính toán đối với các số lớn. II. Các bài toán cơ bản Bài toán 1. Cộng 2 số lớn. Input: Cho S1, S2 là 2 số nguyên dương, mỗi số có số chữ số <=200 (nhập dưới dạng xâu) Output: S1+S2. Thuật toán: Tạo các thủ tục : +procedure DOI (S:string, Var a :mang); { đổi các kí tự số từ S thành các số tương ứng trong mảng a (với thứ tự ngựợc lại)} Var n, i, cod: integer; Begin n:=length(S); For i:= n downto 1 do Begin val(s[i],a[n-i],cod) End ; +Procedure CONG (a,b: mang; var c:mang); Var nho, tg: integer; Begin Nho:=0; For i:= 0 to 300 do Begin Tg:=a[i]+b[i]+ nho; c[i]:=tg mod 10; nho:=tg div 10; End; End; + procedure INKQ (c:mang); Var sc,i: integer; Begin For sc :=300 downto 0 do if c[sc]0 then break; For i:=sc downto 0 do write(c[i]); End; Begin {main} READLN( S1, S2); DOI(S1,a); DOI(S2,b); CONG (a,b,c); INKQ(c); End. Bài toán 2. Hiệu 2 số lớn. Input : S1, S2 Xâu biểu diễn số (giả thiết s1≥ s2) Output : S1- S2. Begin Readln(S1, S2); DOI(s1,a); DOI(s2,b); TRU(a,b,h); INKQ(h); End. Procedure TRU(a,b:mang;var h:mang); Var Begin Muon:=0; For i:=0 to 300 do Begin b[i]:=b[i]+muon; If a[i]>=b[i] then begin h[i]:=a[i]-b[i]; muon:=0;end Else Begin muon:=1; h[i]:=10+a[i]-b[i]; End; End; Bài 3. So sánh 2 số lớn. Input: S1, S2 2 số có số chữ số <=200. Output: sắp xếp lại 2 xâu để S1>=S2. Prorcedure sosanh(X,Y: string; Var biger, equal, less: Boolean); Begin biger:=false; equal:=false; less:=false; nx:=length(X); ny:=length(Y); If X=Y then equal:=true Else if nx> ny then biger:=true Else if ny> nx then less:=true Else Begin i:=0; While (X[i+1]=Y[i+1]) and (i<nx) do inc(i); If i=nx then equal:=true; Else if X[i]>Y[i] then Biger:=true Else less:=true; End; End; Begin{ Main} READLN (S1,S2); SOSANH(S,S2,big, eq,les); If les then begin tg:=S1; s1:=s2; s2:=tg; end; INKQ(S1, S2); End. Bài 4 Nhân một số lớn với một số nguyên dương ( trong pv máy tính) Input : S - Xâu biểu diễn số lớn , n –số nguyên dương. Output: S.n BEGIN Nhập S, nhập n DOI(S,a){ doi xâu số S thành mảng a[0],, a[n]) NHAN(a,n,T) { nhân a với n cho mảng tích T} GHIKQ(T); END. PROCEDURE NHAN(a:mang; n:integer; Var T:mang); Var Begin Fillchar(T,sizeof(T),0); Nho:=0; Tg:=0; For i:=0 to 300 do Begin Tg:=a[i]*n +nho; T[i]:= Tg mod 10; Nho:=tg div 10 End; End; Bài 5. Nhân 2 số lớn. Input: 2 số S1, S2. Output S1.S2. Thuật toán: + Khai báo các mảng các byte: TG, KQ,a,b + DOI(S1,a); DOI(S2,b); + for i:=0 to 300 do Begin Nhan(a, b[i],TG); For j:= 0 to 300 do CONG( TG, KQ, i); End; + INKQ; + cài đặt Procedure CONG(TG: mang; var KQ: mang; i: integer); Var nho, t: integer; Begin Nho:=0; t:=0; For j:=0 to 300 do Begin t:=KQ[j+i]+TG[j]+nho; KQ[j+i]:= t mod 10; nho:= t div 10; End; End; III. Các bài toán ứng dụng. Bài 1. Giai thừa. Input : n nguyên dương n<=200. Output:Tính giai thừa n!. Thuật toán: + Khai báo mảng : GT[0..1000] of byte { chứa kết quả}; + Khởi tạo a[0]:=1 + For i:=1 to n do NHAN(i, a); {Chú ý đầu tiên khởi tạo a[0]:=1} + GHIKQ Bài 2. Tổng luỹ thừa. Tính Pn+Qm. (P,Q ,m , n nguyên dương<=200) Thuật toán: + Xây dung thủ tục PROCEDURE LT(K, n: integer, var A:mang); {nâng K lên luỹ thừa n, kết quả ghi vào mảng A} For i:=1 to n do NHAN( K,a) {chú ý đầu tiên khởi tạo a[0]:=1} + Gọi thủ tuc LT(P,n,A), LT(Q.m,B) +Gọi thủ tuc CONG(A, B, C); + Ghi C. Bài 3. Ghép HCN Input: a , b, c , d , với a,b,c,d nguyên dương là kích thước 2 hình chữ nhật a x b và c x d . Hỏi từ 2 hcn đó có thể ghép được thành một hcn Output : 2 hcn đó có thể ghép được thành một hcn khác. Nếu ghép được cho biết chu vi lớn nhất có thể. Bài 4. BCNN Cho dãy số nguyên dương a1, a2, a3,, an (n<=10000, 0<ai<109). Tìm BCNN(a1,a2,,an) (Đề thi HSG Hà nội 2010) Thuật toán: + Xét dãy các số nguyên tố trong khoảng tứ 2 đến n: Snt:=0; For p:=2 to n do If OK (P) then {if P nguyên tô} Begin Inc(snt) NT[snt]:=p; + Xét dãy số mũ max của số nguyên tố NT[i] là ước của a1,a2,.. Khởi tạo Mmax[i]:=0;(i=1..snt) + for i:= 1 to n do {xét a1, a2,} Begin Tg:=a[i]; For j:= 1 to snt do Begin mm:=0 While tg mod nt[j] =0 do Begin Tg:= tg div nt[j]; Inc(mm) End; If mm>mmax[j] then mmax[j]:=mm; End; End; + Gọi mảng bc[0], bc[1],,,bc[300] là BCNN (ghi theo tt ngược) +Khởi tao bc[0]:=1 + For i:=1 to snt do If mmax[i]>0 then For j:= 1 to mmax[i] do nhan (bc, nt[i]) + GHI gọi nbc: chỉ số khác không cuối cùng của bc. For nbc:=300 downto 0 do if bc[nbc]0 then break; For i:= nbc downto 0 do write(BC[I]); End.
File đính kèm:
- chuyendesolon.doc