Danh cho GV on thi HSG tin

36 8 0
Danh cho GV on thi HSG tin

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

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

Thông tin tài liệu

MỘT SỐ BÀI TẬP THAM KHẢO BÀI 1: - Số siêu nguyên tố Số siêu nguyên tố là số nguyên tố mà khi bỏ một số tuỳ ý các chữ số bên phải của nó thì phần còn lại vẫn tạo thành một số nguyên tố.. [r]

(1)Buổi 1: NHẮC LẠI KIẾN THỨC CƠ BẢN TRONG PASCAL I.Cấu trúc điều khiển 1.Cấu trúc rẽ nhánh if…then a.Dạng thiếu if <Điều kiện> then <Câu lệnh>; *Hoạt động: Kiểm tra điều kiện, điều kiện đúng thì thực Câu lệnh b.Dạng đủ If <Điều kiện> then <Câu lệnh 1> Else <Câu lệnh 2>; *Hoạt động: Kiểm tra điều kiện, điều kiện đúng thì thực Câu lệnh 1, điều kiện sai thì thực Câu lệnh 2.Câu lệnh rẽ nhánh Case…of *Cú pháp: Case <Biểu thức số nguyên kí tự> of <Danh sách 1>: Câu lệnh 1; <Danh sách 2>: Câu lệnh 2; …… <Danh sách n>: Câu lệnh n [Else Câu lệnh n+1]; End; *Hoạt động: Khi gặp câu lệnh case…of máy tính tính giá trị biểu thức trả giá trị nào thì thực câu lệnh tương ứng danh sách, khác thì thực câu lệnh n+1 *Ví dụ: Nhập vào số nguyên là tháng và năm Cho biết tháng đó có bao nhiêu ngày? Program vidu1; Uses crt; Var T,N,SN:integer; Begin Clrscr; Write(‘Nhap thang va nam’); readln(T,N); Case T of 4,6,9,11: SN:=30; 2: if (N mod 400=0) or ((N mod 100<>0) and (N mod 4=0)) then SN:=29 Else SN:=28; Else SN:=31; End; Writeln(‘Thang ’,T, ‘ nam ’,N,’ Co so ’,SN); Readln End 3.Cấu trúc lặp For…do *Cú pháp: For <Biến đếm>:=<Giá trị đầu> to <Giá trị cuối> <Câu lệnh>; For <Biến đếm>:=<Giá trị cuối> downto <Giá trị đầu> <Câu lệnh>; 4.Cấu trúc While…do *Cú pháp: While <điều kiện> <câu lệnh>; 5.Cấu trúc lặp Repeat…until *Cú pháp: Repeat <Dãy câu lệnh>; Until <Điều kiện>; *Ví dụ: Kiểm tra số nguyên dương N nhập vào từ bàn phím có thỏa mãn điều kiện (0<=N<=1000)? Repeat Write(‘Nhap so nguyen N=’); Readln(N); Until (n>=0) and(n<=1000); (2) II.Kiểu liệu có cấu trúc 1.Kiểu mảng chiều *Khái niệm: Mảng chiều là dãy hữu hạn các phần tử cùng kiểu có tên chung, các phần tử này đánh số gọi là số các phần tử *Cú pháp khai báo: Var <Tên biến mảng>:array[n1 n2] of <Kiểu dl>; 2.Kiểu mảng chiều *Khai báo: Var <Tên biển mảng>:array[m1 m2,n1 n2] of <Kiểu dl>; *Ví dụ: Chương trình sau tính và đưa màn hình bảng nhân Program bangnhan; Uses crt; Var A:array[1 9,1 10] of integer; i,j:integer; begin for i:=1 to for j:=1 to 10 a[i,j]:=i*j; for i:=1 to begin for j:=1 to 10 write(a[i,j]:4); writeln; end; readln; end *Bài tập nhà: Bài 1:Cho mảng chiều m hàng, n cột Hãy điền các số nguyên dương từ đến m*n vào mảng chiều cho mảng thứ tự theo hình vẽ: (ví dụ m=3, n=4 thì mảng có dạng sau: 1234 8765 10 11 12 Bài 2: Nhập vào số nguyên dương N (2<N<10000) và dãy a1, a2,….an các phần tử nguyên dương Cho biết dãy trên có bao nhiêu phần tử khác Bài 3: Cho N gói kẹo (N<200) đánh số từ đến N, gói kẹo thứ i có cái kẹo(ai<200) Hãy các gói kẹo thành phần cho độ chênh lệch là ít (3) Buổi 2: NHẮC LẠI KIẾN THỨC CƠ BẢN TRONG PASCAL *Chữa bài tập nhà Bài 1: Gợi ý dùng vòng for để điền các số vào mảng Nếu số hàng lẻ thì ta điền theo số cột tăng Nếu số hàng chẵn thì ta điền theo số cột giảm Viết màn hình mảng vừa điền T:=1; For i:=1 to m Begin If i mod 2<>0 then For j:=1 to n Begin A[I,j]:=T; T:=T+1; End Else For j:=N downto Begin A[I,j]:=T; T:=T+1; End program zizac; uses crt; const nmax=10; var A:array[1 nmax,1 nmax]of integer; m,n,i,j:integer; T:longint; begin clrscr; write('Nhap so hang so cot '); readln(m,n); T:=1; for i:=1 to m begin if i mod <> then begin for j:=1 to n begin a[i,j]:=T; inc(T); end; end else for j:=n downto begin a[i,j]:=T; inc(T); end; end; for i:=1 to m begin for j:=1 to n write(a[i,j]:4); writeln; end; readln end (4) Bài 2: Để làm bài này ta dùng thuật toán “lùa bò vào chuồng”, Các phần tử nhốt chung chuồng, có bao nhiêu chuồng thì có nhiêu phần tử khác dãy ban đầu Ta đóng dãy chuồng C, đánh số chuồng từ 1,2….32000 ( là các số nguyên dương, ai<32000), ban đầu các chuồng trống) Duyệt mảng A ban đầu, phần tử “nhốt” vào chuồng có số (tăng C[a[i]] lên đơn vị) Đếm số chuồng khác trống đó chính là số phần tử khác dãy ban đầu …… Var C:array[0 32000] of integer; ……… Ban đầu khởi tạo chuồng C trống Fillchar(C,sizeof(C),0); For i:=1 to N inc(C[a[i]]); D:=0; For j:=0 to 32000 if C[j]<>0 then inc(D); Write(‘So phan tu khac la’,D:4); program sophantukhacnhau; uses crt; var A:array[1 10000] of integer; C:array[0 maxint] of integer; i,j,n,D:integer; begin clrscr; randomize; write('Nhap so phan tu cua day '); readln(n); for i:=1 to n a[i]:=random(maxint)-random(100); writeln('Day phan tu la '); for i:=1 to n write(a[i]:8); fillchar(C,sizeof(C),0); for i:=1 to N inc(C[a[i]]); D:=0; for j:=0 to maxint if c[j]<>0 then inc(D); writeln('So phan tu khac cua day la ',D:4); readln end Bài 3: Dùng trục số với các điểm chia nguyên 0->40000 để đánh dấu tổng số kẹo có thể sinh xếp số gói kẹo nào đó lại với Ta xét gói kẹo từ a1->an G/s bây xét đến gói ai, để tạo các tổng mới, ta cộng vào tổng đã có (Cộng từ tổng lớn tổng nhỏ là 0) Mỗi sinh tổng mới, cần ghi nhớ số hiệu vừa gộp vào để có tổng này … Từ điểm X là điểm đánh dấu nửa tổng tất số kẹo (Nếu có) điểm đánh dấu gần x (Nếu X không đánh dấu) biết gói cuối cùng thêm vào, trừ số kẹo gói đó ta đến tổng mới, lại biết số kẹo nào vừa thêm vào để tạo tổng này….Quá trình tiếp tục ta điểm đánh dấu Chương trình sau lay dl từ tệp chiakeo.int sau ket qua ghi tệp chiakeo.out program chiakeo; uses crt; const fi='chiakeo.int'; fo='chikeo.out'; maxn=200; maxk=200; maxs=40000; (5) type m1=array[0 maxs] of byte; m2=array[1 maxn] of byte; var a:m2; t:m1; sum:word; n:byte; { -} procedure nhap; var f:text; i:byte; begin sum:=0; assign(f,fi); reset(f); readln(f,n); {so goi keo lan n} for i:=1 to n begin read(f,a[i]); sum:=sum+a[i]; {sum la tong so keo} end; close(f); end; { -} procedure danhdau; var i:byte; max,j:word; begin fillchar(T, sizeof(T),0); T[0]:=1; { danh dau tong =0 da duoc sinh ra} Max:=0; for i:=1 to n begin for j:=max downto {Soat lai cac tong da co tu max ve 0} if T[j]>0 then if T[j+a[i]]=0 then T[j+a[i]]:=i; {danh dau tong j+a[i] vua sinh goi i them vao} max:=max+a[i]; end; end; { } procedure timkq; var i,tong:integer; f:text; kq:m2; begin fillchar(kq,sizeof(kq),0); assign(f,fo); rewrite(f); tong:=sum div 2; while T[tong]=0 dec(tong); writeln(f,sum-tong-tong); repeat kq[t[tong]]:=1; tong:=tong-a[t[tong]] until tong=0; (6) for i:=1 to n if kq[i]=1 then write(f,'Cac goi thuoc phan ',i,' '); writeln(f); for i:=1 to n if kq[i]=0 then write(f,'Cac goi thuoc phan ',i,' '); close(f); end; { -} Begin clrscr; nhap; danhdau; timkq; end 3.Kiểu xâu *Khai báo Var <biến xâu>:string[độ dài]; * Một số hàm và thủ tục liên quan đến xâu -Length(S): Cho độ dài xâu S -Upcase(ch): Cho kí tự in hoa ứng với ch -Pos(s1,s2): Cho vị trí xuất đầu tiên S1 S2, s1 không có s2 hàm cho giá trị -Insert(s1,s2,vt): Chèn xâu s1 vào xâu s2 vị trí vt -Delete(s,vt,n): Xóa xâu s n kí tự từ vị trí vt -Copy(s,vt,n): Sao chép xâu S n kí tự từ vị trí vt -str(x,s): Biến đối số x thành xâu kí tự biểu diễn số đó -Val(s,x,loi): Đổi xâu s thành số chứa x, đổi thành công loi nhận giá trị 0, ngược lại loi nhận giá trị là vị trí kí tự sai s -Concat(s1,s2,…,sn): Ghép các xâu thành xâu.Nếu tổng độ dài các xâu lớn 255 thì máy tính báo lỗi … Bài 1: Cho xâu S, kiểm tra xâu S có là xâu đối gương không? Bài 2: Cho xâu S gồm các chữ cái Cho biết xâu S có bao nhiêu chữ cái khác Mỗi chữ cái xuất bao nhiêu lần Bài 3: Cho xâu S gồm các kí tự chữ số hệ thập phân biểu diễn số nguyên dương có không quá 200 chữ số Hãy tìm cách xóa k chữ số khỏi xâu S nói trên để xâu S thu biểu diễn số có giá trị nhỏ 4.Kiểu liệu tập hợp Khi xử lí liệu gồm các phần tử mà không cần lưu tâm đến quan hệ thứ tự chúng, người ta có thể khai báo liệu theo kiểu tập hợp *Khai báo: type <tên kiểu>=set of <kiểu sở>; Var <tên biến>:<tên kiểu>; Hoặc var <tên biến>:set of <kiểu sở>; *Ví dụ: Khai báo biến b là tập hợp chứa các kí tự Type ks=set of char; Var b:ks; *Người ta kí hiệu tập hợp cặp ngoặc vuông, bên chứa cá giá trị tập thuộc tập hợp đó: ví dụ A=[1,4,10] Một phần tử thuộc tập hợp đó kí hiệu là x in A *Một số phép toán trên tập hợp (7) -Phép hợp: Kí hiệu A+B -Phép giao: Kí hiệu A*B -Phép hiệu: Kí hiệu A-B -Phép thuộc: Kí hiệu A<=B Bài tập áp dụng Bài 1: Hai từ gọi là bạn bè chúng tạo nên cùng số kí tự giống nhau: Ví dụ S1=’aabbbccccb’ và xâu S2=’aabccccaaaaa’ là bạn bè Viết chương trình nhập xâu từ bàn phím, kiểm tra xâu có là bạn bè không? Thuật toán: Ta đổi xâu thành chữ in hoa, tạo tập hợp t1, t2 rỗng Duyệt xâu s1 kiểm tra kí tự kí tự xét s1[i] chưa có tệp t1 thì thêm kí tự này vào tệp Tương tự với xâu s2 và tập hợp t2 So sánh tập hợp chúng thì kết luận xâu là bạn bè uses crt; type kt=set of char; var t1,t2:kt; s1,s2:string; i,n,m,j:byte; begin clrscr; writeln('Nhap xau 1='); readln(s1); writeln('Nhap xau 2='); readln(s2); for i:=1 to length(s1) s1[i]:=upcase(s1[i]); for j:=1 to length(s2) s2[j]:=upcase(s2[j]); t1:=[]; t2:=[]; for i:=1 to length(s1) if not(s1[i] in t1) then t1:=t1+[s1[i]]; for j:=1 to length(s2) if not(s2[j] in t2) then t2:=t2+[s2[j]]; if t1=t2 then writeln('Hai xau la ban be ') else writeln('Hai xa khong la ban be'); readln end Bài 2: Như các bạn đã biết dãy số Fibonaci là dãy 1, 1, 2, 3, 5, 8, Dãy này cho công thức đệ qui sau: F1 = 1, F2 =1, Fn = Fn-1 + Fn-2 với n > Tính số hạng thứ n dạy Fibonaci Chương trình nhập n từ bàn phím và viết màn hình số hạng thứ N dãy Fibonaci GV Hướng dẫn hs viết chương trình này Ta khai báo mảng lưu lại các số fibonaci tính được, viết màn hình số hạng thứ n Var F:array[1 nmax] of longint; F[1]:=1; F[2]:=2; For i:=3 to n F[i]:=F[i-1]+F[i-2]; Writeln(‘So hang thu n=’,F[n]); Bài 3:Nhập vào số nguyên không âm, kiểm tra xem nó có phải là số nguyên tố hay không? Với bài này các em viết hàm kiểm tra tính nguyên tố số dương n bất kỳ, hàm trả giấ trị True N nguyên tố, ngược lại hàm trả giá trị False Function NT(n:longint):Boolean; Var i:longint; kq:boolean; (8) Begin If (n=0) or (n=1) then kq:=false Else i:=1; Repeat i:= i+1; Until (n mod i= 0) or (i*i>sqrt(n)); If i*i>sqrt(n) then kq:=true Else kq:=false; NT:=kq; End (9) Bài In các số nguyên tố nhỏ N (N là số nguyên không âm nhập từ bàn phím) Với bài tập này các em sử dụng hàm trên để kiểm tra các số i<N, NT(i)=true thì ta viết i màn hình program songuyenton; uses crt; var N,i:longint; function NT(n:longint):boolean; var i:longint; kq:boolean; begin if (n=0) or (n=1) then kq:=false else begin i:=1; repeat i:=i+1; until (n mod i=0) or (i*i>n); if i*i>n then kq:=true else kq:=false; end; NT:=kq; end; begin clrscr; writeln('Nhap so n='); readln(N); if n<2 then writeln('Khong co so nt nao nho hon ',n) else for i:=2 to N if NT(i) then write(i:4); readln end Thuật toán này dễ cài đặt có hạn chế là thời gian thực lâu vì với số lại phải kiểm tra các ước nó thời gian thực tính là n2 Với n càng lớn thời gian thực lâu Có thuật toán xem là tốt đó là thuật toán sàng các số nguyên tố Biểu diễn các só nguyên trên trục số số đến N sau đó tìm cách xóa dần các điểm biểu diễn hợp số, các điểm còn lại trên trục số biểu diễn số nguyên tố cụ thể: -Ban đầu tất các điểm nguyên trên trục số chưa bị xóa; -Số đầu tiên chưa bị xóa là số (đó là số nguyên tố) , xóa các bội -Số đầu tiên chưa bị xóa là số (Số nguyên tố), xóa các bội ….quá trình tiếp diễn với các số chưa bị xóa i mà i*i<N Chương trình uses crt; var n,i,j:longint; a:array[1 maxint] of 1; begin clrscr; write('nhap so n='); readln(n); fillchar(a,sizeof(a),0); (10) i:=2; while i*i<=n begin j:=i+i; while (j<=n) begin a[j]:=1; j:=j+i; end; inc(i); while a[i]=1 inc(i); end; for i:=2 to N if a[i]=0 then write(i:4); readln end Bài 5- Dãy số Fibonaci Như các bạn đã biết dãy số Fibonaci là dãy 1, 1, 2, 3, 5, 8, Dãy này cho công thức đệ qui sau: F1 = 1, F2 =1, Fn = Fn-1 + Fn-2 với n > Chứng minh khẳng định sau: Mọi số tự nhiên N có thể biểu diễn dạng tổng số số dãy số Fibonaci N = akFk + ak-1Fk-1 + a1F1 Với biểu diễn trên ta nói N có biểu diễn Fibonaci là akak-1 a2a1 Cho trước số tự nhiên N, hãy tìm biểu diễn Fibonaci số N Input: Tệp văn P11.INP bao gồm nhiều dòng Mỗi dòng ghi số tự nhiên Output: Tệp P11.OUT ghi kết chương trình: trên dòng ghi lại biểu diễn Fibonaci các số tự nhiên tương ứng tệp P11.INP {$R+} const Inp = 'f11.int'; Out = 'f11.out'; Ind = 46; var n: LongInt; Fibo: array[1 Ind] of LongInt; procedure Init; var i: Integer; begin Fibo[1] := 1; Fibo[2] := 1; for i := to Ind Fibo[i] := Fibo[i - 1] + Fibo[i - 2]; end; (11) procedure Solution; var i: LongInt; hfi, hfo: Text; begin Assign(hfi, Inp); Reset(hfi); Assign(hfo, Out); Rewrite(hfo); while not Eof(hfi) begin Readln(hfi, n); Write(hfo, n, ' = '); i := Ind; while Fibo[i] > n Dec(i); Write(hfo, Fibo[i]); Dec(n, Fibo[i]); { giảm n Fibo[i] đơn vị} while n > begin Dec(i); if n >= Fibo[i] then begin Write(hfo, ' + ', Fibo[i]); Dec(n, Fibo[i]); end; end; Writeln(hfo); end; Close(hfo); Close(hfi); end; begin Init; Solution; end Bài 6: Giai thừa (Đề thi HSG tỉnh năm 2010-2011) Giai thừa số cho công thức sau: n!=1*2*…*n Cho số N (N<=2.109) nguyên dương tính tổng giai thừa các chữ số chủa nó Trong bài các em viết hàm tính giai thừa số nguyên dương N Sử dụng hàm này để tính tổng các chữ số số program tonggiai; uses crt; var SUM:longint;x,n,t:integer; function GT(n:integer):Longint; var i:integer;T:longint; begin if n=0 then T:=1 else begin T:=1; for i:=1 to n (12) T:=T*i; end; GT:=T; end; begin clrscr; write('Nhap n='); readln(N); sum:=0; t:=n; while n>0 begin x:=n mod 10; SUM:=SUM+GT(x); n:=n div 10; end; write('Giai thua cua ',t,'=',sum); readln end Bài 7: (Đề thi HSG tỉnh năm 2010-2011) Dãy số Fibinaci Cho số nguyên dương N (N<=2.109) Hãy kiểm tra xem n có là số thuộc dãy Fibinaci không? Nếu có thì là số bao nhiêu dãy? Yêu cầu hs dựa vào chương trình bài tự viết chương trình {$R+} uses crt; const Ind = 46; var n: LongInt; Fibo: array[1 Ind] of LongInt; procedure Init; var i: LongInt; begin Fibo[1] := 1; Fibo[2] := 1; for i := to Ind Fibo[i] := Fibo[i - 1] + Fibo[i - 2]; end; procedure Solution; var i: LongInt; begin write('nhap n='); readln(n); i := 1; repeat inc(i); until (Fibo[i]=n) or (i>=Ind); if i=Ind then writeln('NO') else writeln('YES ',i); readln end; begin (13) Init; Solution; end (14) Bài 8: Số chữ số tận cùng (Đề thi HSG tỉnh năm 2011-2012) Tính chữ số tận cùng N!=1*2*….*N, với số nguyên dương N<=109 N nhập từ bàn phím, kết đưa màn hình gồm số là số chữ số tận cùng N! tìm Ví dụ N=12, kết đưa màn hình là program tonggiai; uses crt; var SUM:longint;t,i,n:integer; s:string; function GT(n:integer):Longint; var i:integer;T:longint; begin if n=0 then T:=1 else begin T:=1; for i:=1 to n T:=T*i; end; GT:=T; end; begin write('Nhap n='); readln(N); SUM:=GT(n); t:=0; str(SUM,s); {Hàm str(SUM,s) đổi số SUM thành xâu S để đếm số cuối xâu} i:=length(s); while s[i]='0' begin inc(t); dec(i); end; writeln('Cho so o tan cung cua ',N,'=',t); readln end (15) Buổi Một số bài tập Bài 1: Bài tập tìm các số siêu nguyên tố có n chữ số Bài này có thuật toán không đệ quy Tạo các số siêu nguyên có i chữ số từ các số siêu nguyên tố có i-1 chữ số Code Khởi tạo a mảng chứa các số nguyên tố Gs: có đem so a For i:=2 to N Begin For j:=1 to dem {tạo mảng b số siêu nguyên tố có i chữ số dựa vào i-1) For k:=0 to Begin x:=a[j]*10+k; if x nguyên tố then Nap vào b End; {mảng b chứa các số nguyên tố cần tìm} a:=b; End; Có thể sử dụng a,b là mảng a[1 2,1 max] thay vì gán mảng program nt; uses crt; const nmax=100000; var b,a:array[1 nmax] of longint; i,j,dem,t,x,n,k:longint; { } Function Prime(N: longint): boolean; Var i: longint; Begin If (N=0) or (N=1) then Prime:=false Else Begin i:=2; While (N mod i <> 0) and (i <= Sqrt(N)) Inc(i); If i > Sqrt(N) then Prime:=true Else Prime:=false; End; End; (16) { -} begin clrscr; writeln('Nhap n='); readln(n); dem:=1; a[1]:=0; for i:=1 to N begin t:=0; for j:=1 to dem for k:=0 to begin x:=a[j]*10+k; if Prime(x) then begin t:=t+1; b[t]:=x; end; end; a:=b; dem:=t; end; for i:=1 to t begin write(a[i],' '); if i mod 10=0 then writeln; end; writeln; writeln('co ',t,' so sieu nguyen to'); readln end Bài (Đề thi HSG Tỉnh năm 2009-2010) Dãy các số tự nhiên viết thành dãy vô hạn trên đường thẳng: 1234567891011121314 (1) Hỏi số vị trí thứ 1000 dãy trên là số nào? Tổng quát lên vị trí thứ k? Hãy làm bài này theo hai cách: Cách dùng suy luận logic và cách viết chương trình để tính toán và so sánh hai kết với (17) Đáp án: chữ số vị trí k = 1000 là số Cách 1: suy luận logic: Ta có dãy số s = 123456789101112 Gọi i là các số thành phần, i thuộc {1,2,3,4, ,10,11, ,100,101,102 ,1000,10001 } Khi i có chữ số: có tối đa số, số chữ số = 9x1 = 9; Khi i có chữ số: có tối đa chữ số chục (1->9) x 10 chữ số đơn vị (0 ->9) = 9x10 = 90 số, số chữ số = 90x2 = 180; Khi i có chữ số: có tối đa 9x10x10 = 900 số, số chữ số tối đa = 900x3 = 2700; Dựa vào đó ta có thể tính từ vị trí k bất kỳ: k < 10 ta có chữ số chính là k k>10: ví dụ k = 31, ta tính 31 - = 22, 22/2 = 11 dư nghĩa là chữ số thứ số thứ 11 tính từ 10, chính là 20 => kết = 0; k>189: ví dụ k = 191, ta tính 191 - 189 = 2, 2/3 = dư nghĩa là chữ số thứ số thứ tính từ 100, => kq = 0; Trường hợp trên k = 1000, ta tính 1000 - 189 = 811, 811/3 = 270 dư nghĩa là chữ số thứ số thứ 270 tính từ 100 Ta có từ 100 tới 299 có 200 số, 70 số còn lại rơi vào khoảng 300 -> 369, số thứ 270 chính là 369 kết cần tìm là Chương trình Const fi='num.inp'; fo='num.out'; Var cs:array[1 7] of longint = (9,180,2700,36000,450000,5400000,63000000); n:longint; f,g:text; Function num(n:longint):char; Var k,so,mu:longint; s:string; Begin k:=1; mu:=1; While (k<9) and (cs[k]<n) Begin (18) n:=n-cs[k]; inc(k); mu:=mu*10; End; If mu=1 then so:=n div k Else so:=n div k+mu+ord(n mod k>0)-1; Str(so,s); s:=s[k]+s; num:=s[n mod k + 1]; End; Begin Assign(f,fi); Reset(f); Assign(g,fo); Rewrite(g); While not seekeof(f) Begin Readln(f,n); Writeln(g,num(n)); End; Close(f); Close(g); End (19) thuật toán đơn giản, là làm bước sau: b1 Xác định xem vị trí n nằm số nguyên nào dãy số "1234567891011121314 " vd: với k=14, thì số nguyên chứa chữ số vị trí thứ 14 chính là số 12 b2 Xác định chữ số cần tìm số nguyên vừa tìm bước vd: với k=14, số nguyên tìm là 12, thì chữ số cần tìm là số - để làm bước thì ta dựa vào quy luật sau: ban đầu với các số nguyên có chữ số thì ta có chữ số, với các số nguyên có chữ số ta có 180 chữ số, là 2700 chữ số, Ta gọi các số 9, 180, 2700, này là d, và số d cần tìm phải là số lớn và <=k, để tìm d ta dùng công thức : d=9*i*10i-1 ( i là số chữ số số nguyên) - sau tìm d, ta xác định số nguyên cần tìm là x=x+ d div i, và k=k-d là số dư còn lại vd: với n=14, ta tìm d là 9, x=9, số dư k=5 - với k còn dư, ta có x=x+(k div i) - là làm bước 2, ta xác định vị trí chứa chữ số cần tìm số nguyên x : k mod i=0 thì vị trí đó chính là chữ số cuối số nguyên vừa tìm, ngược lại thì vị trí đó là i = k mod i - cuối cùng thì dùng hàm str(x,st) để chuyển số thành chuỗi và in chữ số st[i] màn hình uses crt; var st: string; j,n,d,x: longint; i: integer; begin clrscr; write('Nhap n: ');readln(n); i:=1; j:=1; d:=9; x:=0; while (n > d) begin n:=n-d; x:=x+d div i; j:=j*10; (20) i:=i+1; d:=j*9*i; end; x:=x+(n div i); if n mod i>0 then begin x:=x+1; i:=n mod i; end; str(x,st); write('Ket qua: ',st[i]); end Bài Nhập dãy A có N số tự nhiên (N<40) và số K Hãy xuất các phần tử có số lần xuất dãy A từ K lần trở lên ( Mỗi số xuất lần) Dữ liệu nhập: file DAYSO.INP: - Dòng 1: số N, K số cách khỏang trắng - Dòng 2: Dãy A Kết quả: file DAYSO.OUT: xuất các số thỏa điều kiện trên, trường hợp không có số nào thỏa thì xuất số -1 es crt; var a,b:array[0 100] of integer; n,j,i,k:integer; f:text; Procedure docf; begin assign(f,'C:\DAYSO.INP'); reset(f); i:=0; read(f,n); readln(f,k); While not eof(f) begin inc(i); read(f,a[i]); end; close(f); end; Procedure xuly; begin assign(f,'C:\DAYSO.OUT'); rewrite(f); FillChar(b,SizeOf(b),0); For i:=1 to n inc(b[a[i]]); For i:=1 to n if b[i]<>0 then if b[i]>=k then writeln(f,i,' Xuat hien ',b[i], ' lan!'); (21) close(f); end; BEGIN clrscr; docf; xuly; readln end Bài Nhập dãy số thực a và số k Xét xem dãy có k số dương đứng cạnh hay không? Dữ liệu nhập: DUNGCANH.INP: dãy a và số k Dữ liệu xuất: DUNGCANH.OUT có xuất , không có xuất es crt; var a:array[1 100] of real; k,n,j,i,s:integer; f:text; Procedure ghif; begin assign(f,'C:\DUNGCANH.INP'); reset(f); read(f,n); writeln(n); read(f,k); writeln(k); i:=0; While not eof(f) begin inc(i); read(f,a[i]); writeln(a[i]); end; writeln; end; Procedure xuly; var d:integer; begin assign(f,'C:\DUNGCANH.OUT'); rewrite(f); For i:=1 to n Begin d:=1; While (i<=n) and (a[i]>0) and (a[i+1]>0) begin inc(d); if d>=k then Begin s:=1; write(f,s); break; end; end; if s=0 then write(f,s); close(f); end; BEGIN clrscr; ghif; xuly; readln end Bài - Số phản nguyên tố inc(i);end; (22) Một số n gọi là số phản nguyên tố số ước số nó là nhiều n số tự nhiên đầu tiên Cho số K (K <= tỷ) Hãy ghi số phản nguyên tố lớn nhỏ K Dữ liệu vào file PNT.INP nội dung gồm: - Dòng đầu tiên là số M (1 < M <= 100) - số các số cần tìm số phản nguyên tố lớn nó; - M dòng là các số K1, K2, K3, , KM; Dữ liệu file PNT.OUT gồm M dòng: dòng thứ i là số phản nguyên tố lớn nhỏ Ki Ví dụ: PNT.INP 1000 PNT.OUT 840 Bài Một chuỗi kí tự định nghĩa là chuổi bao gồm các kí tự ‘A’ ‘Z’ ‘a’ ‘z’ Một xâu có thể viết thu gọn, bao gồm các ký tự kèm theo số lần xuất liên tiếp ký tự đó Ví dụ: Chuỗi nhất: AABBCDDEEF Chuỗi thu gọn: 2A2BC2D2EF Chuỗi thu gọn: A5B3D2E Chuỗi nhất: ABBBBBDDDEE Yêu cầu: Viết chương trình nhập chuỗi không quá 255 ký tự từ bàn phím là dạng hay dạng thu gọn, ghi chuổi vừa nhập vào tập tin INPUT.TXT ‒ Nếu là chuỗi thì hãy chuyển đổi nó dạng thu gọn ‒ Nếu là chuỗi thuộc dạng thu gọn thì hãy chuyển đổi nó trở lại dạng tương ứng ‒ Kết lưu vào tập tin OUTPUT.TXT nó ko program Nen_giainen_chuoi; var s:string; i,k:integer; function Nen(s:string):string; var i,j,d:integer; c:string; begin for i:=1 to length(s)-1 if s[i]=s[i+1] then begin d:=2; for j:=i+1 to length(s) if (s[i]=s[j+1]) and (j<length(s)) then d:=d+1 else begin str(d,c); insert(c,s,i); delete(s,i+1,d-1); break; end; end; nen:=s; (23) end; function Giainen(s:string):string; var i,j,d,code:integer; c,x:string; begin for i:=1 to length(s) if s[i] in ['0' '9'] then c:=c+s[i] else begin val(c,d,code); for j:=1 to d x:=x+s[i]; c:=''; d:=0; end; giainen:=x; end; begin readln(s); for i:=1 to length(s) if s[i] in ['0' '9'] then begin k:=1; break; end; if k=1 then writeln(giainen(s)) else writeln(nen(s)); readln end (24) For k:=1 to ka a[k]:=b[k]; end; For k:=1 to ka Write(a[k]:10); (25) MỘT SỐ BÀI TẬP THAM KHẢO BÀI 1: - Số siêu nguyên tố Số siêu nguyên tố là số nguyên tố mà bỏ số tuỳ ý các chữ số bên phải nó thì phần còn lại tạo thành số nguyên tố Ví dụ 7331 là số siêu nguyên tố có chữ số vì 733, 73, là các số nguyên tố Nhiệm vụ bạn là viết chương trình nhập liệu vào là số nguyên N (0< N <10) và đưa kết là số siêu nguyên tố có N chữ số cùng số lượng chúng Ví dụ chạy chương trình: Nhap so N: 4 Cac so sieu nguyen to có chu so la: 2333 2339 2393 2399 2939 3119 3137 3733 3739 3793 3797 5939 7193 7331 7333 7393 Tat ca co 16 so_ Program Bai37; {SuperPrime}; var a,b: array [1 100] of longint; N,i,k,ka,kb,cs: byte; Function Prime(N: longint): boolean; Var i: longint; Begin If (N=0) or (N=1) then Prime:=false Else Begin i:=2; While (N mod i <> 0) and (i <= Sqrt(N)) Inc(i); If i > Sqrt(N) then Prime:=true Else Prime:=false; End; End; BEGIN Write ('Nhap N: '); Readln (N); ka:=1; a[ka]:=0; For i:=1 to N Begin Kb:=0; For k:=1 to ka For cs:=0 to If Prime(a[k]*10+cs) then Begin Inc(kb); b[kb]:=a[k]*10+cs; end; ka:=kb; Writeln('Co tat ca',ka,'so sieu nguyen to co',N,'chu so.'); Readln; END (26) Bài 2: Tam giác Pascal là gì? Quy luật Tam giác Pascal đơn giản : hàng thứ ba, số bên là tổng hai số phía trên nó Ví dụ : hàng 3, số là tổng và ; hàng 4, số là tổng và ; hàng 5, số là tổng và Căn theo quy luật đó, Tam giác Pascal là kéo dài đến vô hạn Ví dụ: 232 34543 4567654 567898765 Đoạn code sau in màn hình 10 dòng đầu tam giác Pascal (được giữa) uses crt; const n=10; var i,j:integer; begin for i:=1 to n begin for j:=n downto i write(' '); { <- thêm dấu cách } for j:=i to 2*i-1 write(j:2); { <- đặt chỗ trống cho số} for j:=2*i-2 downto i write(j:2); { <- đặt chỗ trống cho số} writeln; end; readln; end Bài 3: Nhập ngày tháng năm Hãy cho biết ngày tháng năm sau đó N ngày var d,m,y,n:integer; Function Songay(thang,nam: Integer):Integer; Var sn:Integer; Begin Case thang of 1,3,5,7,8,10,12 : sn:= 31; 4,9,11 : sn:= 30; 2: If (nam MOD = 0) Then sn:= 29 Else sn:= 28; End; Songay:= sn; End; BEGIN Writeln('Nhap thang nam');Readln(d,m,y); Writeln('Nhap N');Readln(N); (27) d:=d+N; While d > Songay(m,y) Do Begin d:= d - Songay(m,y); m:= m+1; IF m > 12 Then Begin m:= 1; y:= y + 1; End; End; Writeln('Ket qua ',d,'/',m,'/',y); Readln; END Bài 4:Hai số m,n gọi là bạn tổng các ước m n và ngược lại.Tìm tất các số là bạn và nhỏ 10001 Ý tưởng: Thay vì chạy vòng lặp để xét m và n, ta có thể cần chạy vòng lặp kiểm tra xem m và uoc(m) có là bạn không PROGRAM timban; FUNCTION uoc(k:INTEGER):longint; VAR i,tong:INTEGER; BEGIN tong:=0; FOR i:=1 TO k DIV DO IF k MOD i =0 THEN tong:=tong+i; uoc:=tong; END; VAR m:longint; BEGIN for m:= to 10001 if uoc(uoc(m)) = m then writeln(m, ' va ', uoc(m),' la ban cua nhau'); readln END Bài 5:Nhập vào số tự nhiên n* và nhập vào m, sau đó tính tổng m các số tận cùng n vd: n = 365 m =2 tổng = 5+6=11 Cách 1: uses crt; var n: longint; m,tong,i: integer; (28) BEGIN clrscr; write('Nhap n: '); readln(n); write('Nhap m: '); readln(m); for i:=1 to m begin tong:=tong+(n mod 10); n:=n div 10; end; write('Tong ',m,' chu so cuoi cua so vua nhap = ',tong); readln; END Cách 2: Sử dụng xâu: Xâu giúp lưu trữ thoải mái kiểu số nguyên, nên ta có thể khái báo N có string thay vì Integer Như vậy, trường hợp lớn (vd N bao gồm 100 chữ số chẳng hạn) thuật toán có thể hoạt động bình thường uses crt; var n: string; m,i,a,tong: integer; BEGIN clrscr; write('Nhap so n: '); readln(n); write('Nhap m: '); readln(m); for i:= length(n) downto length(n)-m+1 begin val(n[i],a); tong:=tong+a; end; write(tong); readln; END Như vậy, thay vì dùng lệnh mod nhập N vào dạng số nguyên, ta dùng thủ tục val xâu (biến từ chữ thành số), các bạn có thể xem thêm bài Xâu - String Bài 6: Nhập vào n (1<=n<=30000), hãy in số chữ số cuối cùng n giai thừa Ý tưởng cách tìm: Xét tất các số chia hết cho Giả sử số đó có thể chia hết cho Xi chữ số Cộng tất các Xi đó lại thì ta số chữ số Giả sử 25! = 15511210043330985984000000 có chữ số tận cùng ta có chia hết cho chữ số 10 chia hết cho chữ số 15 chia hết cho chữ số 20 chia hết cho chữ số 25 chia hết cho chữ số -> suy tổng là (đúng với kết là có chữ số 0) (29) var n, i, j, count: longint; begin write('Nhap N (N>=1): '); readln(n); for i:=1 to n begin j:=i; while j mod = begin j:=j div 5; count:=count+1; end; end; write(' So chu so cuoi cua ',n,'! la: ',count); readln; end Bài 7: Cho ột số hệ số 10 đổi sang hệ nhị phận Nguyên tắc phương pháp chuyển đổi từ hệ số 10 sang hệ số là lấy số cần chuyển đổi chia cho (kết lấy phần nguyên), sau đó tiếp tục lấy kết chia (và lấy phần nguyên), kết số nhị phân thu là tập hợp các số dư các phép chia Program Doi_thap_phan_ra_nhi_phan; Var He10,N,Y:Word; He2,Tam:String; Begin Writeln('DOI SO TU HE THAP PHAN SANG HE NHI PHAN'); Writeln(' -'); Writeln; Write('-Nhap so nguyen he thap phan: '); Readln(He10); N:=He10; He2:=' '; Repeat Y:=He10 Mod 2; Str(Y, Tam); He2:=Tam + He2; He10:= He10 Div 2; Until He10 = 0; Writeln; Writeln('+So he 10 la : ',N); Writeln('+Doi sang he la: ',He2); Writeln; Writeln(' Bam phim <Enter> de ket thuc'); Readln End (30) Bài 8: Phân tích số thừa số nguyên tố Ví dụ: Phân tích 12=2*2*3 Ý tưởng: Thuật toán phân tích số thừa số nguyên tố tương tự thuật toán kiểm tra số nguyên tố Điểm khác đây là kiểm tra số nguyên tố ta phải kiểm tra các số nhỏ sqrt(n) (căn bậc hai n) có phải là ước n hay không, còn phân tích ta việc chia n cho các số nguyên số nguyên tố nhỏ là Khi không chia thì ta tăng số chia lên đơn vị, quá trình phân tích kết thúc n VAR i,n :INTEGER; BEGIN Write ('Nhap n:'); Readln(n); Write (n,'='); i:=2; REPEAT WHILE n MOD i <> DO i:=i+1; Write(i); n:=n DIV i; IF n > THEN write ('*'); UNTIL n = 1; readln; END Bài 9:Viết chương trình nhập vào xâu, đưa xâu đảo theo từ Ví dụ: xe đạp -> đạp xe uses crt; var s:string; x,y,z,t:byte; begin write('Nhap vao mot xau: '); readln(s); z:=length(s); for y:=length(s) downto begin if ((s[y]=' ')or(y=1)) then begin for t:=y to z write(s[t]);z:=y end; write(' '); end; readln; end Bài 10: Dãy số tự nhiên a1 , a2 ,a3 ak gọi là hạnh phúc nó thoả mãn các điều kiện sau : - Dãy trên là dãy giảm dần - Với i ( 1<=i <= k ) là số nguyên tố , phải là ước các số a1 , a2 , , VD : 18 17 13 11 là dãy hạnh phúc (31) Viết chương trình nhập số tự nhiên N từ bàn phím và in màn hình dãy số hạnh phúc càng dài càng tốt với số hạng đầu tiên là N Uses crt; Const max=37; Var a:array[1 max] of longint; n,i:longint; BEGIN Clrscr; a[1]:=1; a[2]:=1; a[3]:=2; For i:=4 to max a[i]:=a[i-1]+a[i-2]+a[i-3]; Write('Nhap so n:'); readln(n); i:=max; While a[i]>n i:=i-1; Write(n,'=',a[i]); n:=n-a[i]; While n>0 Begin i:=i-1; If n>=a[i] then Begin Write('+',a[i]); n:=n-a[i]; End; End; Readln; END Bài 11: Trước hết, chúng ta tìm hiểu khái niệm số chính phương Số chính phương là gì? Số chính phương là số mà tự nó là bậc hai số tự nhiên khác, hay nói rõ thì số chính phương là bình phương số tự nhiên Ví dụ: 289 là số chính phương vì 289 = 17 bình phương Thuật toán Pascal đây giúp tìm số chính phương mảng chiều uses crt; type ArrInt = array[1 250] of integer; Var n,i,x : integer; a: ArrInt; BEGIN clrscr; write('Nhap so phan tu: '); readln(n); for i:=1 to n begin write('Phan tu thu ',i,'= '); (32) readln(a[i]); end; writeln('Cac so chinh phuong co mang:'); for i:=1 to n begin x:=trunc(sqrt(a[i])); if sqr(x)=a[i] then write(a[i]:4); end; readln; END Bài 12 Viết chương trình nhập mảng chiều có N phần tử In màn hình các phần tử có dạng 3k+2 (k=0,1,2,3 ) Ý tưởng: Viết hàm kiểm tra xem phần tử a[i] có dạng 3^k+2 hay không uses crt; var b,j,i,x:integer; a:array[1 100] of integer; Function gt(k:integer):longint; var j:integer;s:longint; begin s:=1; for j:=1 to k s:=s*3; gt:=s; end; { -} Function kt(x:integer):boolean; var i,j,k:integer;s:longint; begin kt:=false; s:=1; k:=0; Repeat inc(k); gt(k); Until gt(k)>=x-2; if gt(k)=x-2 then kt:=true; end; (33) { -} begin clrscr; Write('Nhap so phan tu= ');readln(x); For i:=1 to x begin write('a[',i,']= '); readln(a[i]); end; For i:=1 to x if kt(a[i]) then write(a[i],' ');writeln; readln end Một số thuật toán xếp Sắp xếp là thuật toán không ngôn ngữ lập trình Pascal mà còn nhiều lĩnh vực công nghệ khác Bài viết sau để cập đến số thuật toán xếp ngôn ngữ Pascal Bubble Sort (Sắp xếp bọt) Ý tưởng: Giả sử có mảng có n phần tử Chúng ta tiến hành duyệt từ cuối lên đầu,so sánh phần tử kề nhau, chúng bị ngược thứ tự thì đổi vị trí, việc duyệt này cặp phần tử thứ n-1 và n Tiếp theo là so sánh cặp phần tử thứ n-2 và n-1,… so sánh và đổi chỗ cặp phần tử thứ và thứ hai Sau bước này phần tử nhỏ đã lên vi trí trên cùng (nó giống hình ảnh các “bọt” khí nhẹ lên trên) Tiếp theo tiến hành với các phần tử từ thứ đến thứ n Procedure bubblesort(var amang; Ninteger); begin var i,j integer; for i=2 to N for j=N down to i if (a[j] a[j-1]) then hoanvi(a[j-1],a[j]); end; Selection Sort (Sắp xếp chọn) Ý tưởng: Chọn phần tử nhỏ n phần tử ban đầu, đưa phần tử này vị trí đúng là đầu tiên dãy hành Sau đó không quan tâm đến nó nữa, xem dãy hành còn n-1 phần tử dãy ban đầu, vị trí thứ Lặp lại quá trình trên cho dãy hành đến dãy hành còn phần tử Dãy ban đầu có n phần tử, tóm tắt ý tưởng thuật toán là thực n-1 lượt việc đưa phần tử nhỏ dãy hành vị trí đúng đầu dãy (34) Các bước tiến hành sau: Bước 1: i=1 Bước 2: Tìm phần tử a[min] nhỏ dãy hành từ a[i] đến a[n] Bước 3: Hoán vị a[min] và a[i] Bước 4: Nếu i<=n-1 thì i=i+1; Lặp lại bước Ngược lại: Dừng n-1 phần tử đã nằm đúng vị trí Procedure seletionsort(var a:mang; N:byte); var i,j: byte; min: integer; begin for 1:=1 to N-1 if (a[j] < a[min] then min:=j; if (min <> i) then hoanvi (a[min]; a[i]; end; Procedure hoanvi(var x,y: integer); var tam:integer begin tam:=x x:=y y:=tam end; Insert Sort Procedure insertionsort(var a:mang, N:byte); begin var pos,i: byte; x:integer; for i:=2 to N begin x:=a[i]; pos:=i; {sap xep tang dan} while (pos>1 and a[pos-1]>x)do begin a[pos]:= a[pos-1]; dec(pos); end; a[pos]:= x; end; {sap xep giam dan} while (pos>1) begin if(a[pos-1] > x)then begin a[pos]:= a[pos-1]; dec(pos); end; a[pos]:= x; (35) QuickSort procedure Quicksort ( Var A: Mang); Procedure Sort( Left, Right: Integer); Var i, j, k: Integer; Begin i:= Left; j:= Right; k:= A[(Left + Right) Div 2]; Repeat While A[i] < k Do Inc(i); While k < A[j] Do Dec(j); If i <> j Then Begin HoanVi(A[i],A[j]); Inc(i); Dec(j); end; Until i > j; If Left < j Then Sort(Left,j); If i < Right Then Sort(i,Right); end; Begin Sort(Left; Right); End; (36) (37)

Ngày đăng: 04/06/2021, 03:21

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

  • Đang cập nhật ...

Tài liệu liên quan