1. Trang chủ
  2. » Công Nghệ Thông Tin

Thuật toán học trong tin học

11 978 10
Tài liệu đã được kiểm tra trùng lặp

Đ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

Thông tin cơ bản

Định dạng
Số trang 11
Dung lượng 160 KB

Nội dung

Thuật toán học trong tin học

Trang 1

ứng dụng lý thuyết Toán để giải các bài Tin

Lê Nguyễn Tuấn Thành

(Tiếp theo số trước)

Bài 8

Câu 1 Cho một số thập phân vô hạn tuần hoàn dạng A,B(C) với A là phần trước dấu

phẩy, B là phần sau dấu phẩy không tuần hoàn, C là phần thập phân tuần hoàn (A,B,C là các số nguyên dương, C<>9) Hãy viết phân số tối giản biểu diễn số thập phân đó

File vào: Thapphan.inp

Gồm: 3 số A,B,C ghi trên 3 dòng khác nhau Nếu B= -1 thì sau dấu phẩy của số đóự chỉ

có phần vô hạn tuần hoàn

File ra : Thapphan.out

Gồm : Tử và mẫu của phân số tìm được, ghi trên hai dòng

Câu 2: Cho phân số có tử và mẫu lần lượt là P,Q (P,Q là các số nguyên dương) Hãy viết

dạng biểu diễn thập phân của phân số đó

File vào : Fraction.inp

Gồm: P,Q ghi trên cùng một dòng cách nhau bởi dấu cách

File ra: Fraction.out

Gồm: Nếu biểu diễn thập phân là vô hạn tuần hoàn thì ghi ra dạng A B C với ý nghĩa như

câu 1

Nếu biểu diễn thập phân là hữu hạn thì ghi ra

dạng A B

Giải

Để giải quyết bài này trước hết tôi nhắc lại 2 định lí quan trọng về phân số được đề cập đến trong SGK lớp 7:

Định lí 1: Nếu một phân số tối giản mà mẫu lớn hơn 0 và mẫu không có ước nguyên tố

nào khác 2 và 5 thì phân số đó được viết dưới dạng số thập phân hữu hạn

Định lí 2: Nếu một phân số tối giản mà mẫu lớn hơn 0 và mẫu có ước nguyên tố khác 2

và 5 thì phân số đó được viết dưới dạng số thập phân vô hạn tuần hoàn Bây giờ ta sẽ đi tìm phân số biểu diễn của một số thập phân vô hạn tuần hoàn dạng 0,(c) Gọi k là số chữ

số của c

Trang 2

Nếu bạn nào tinh ý sẽ để ý thấy rằng số thập phân 0,(9) sẽ không có phân số nào biểu diễn, bởi vì theo trên

Điều này không đúng Trong chương trình tôi viết cho Câu 1 nếu nhập vào 0 −1 9 thì kết

quả nhận được là

Đây có lẽ là sự thú vị nhất về số thập phân vô hạn tuần hoàn

Định lí 1 và 2 khẳng định mọi phân số đều có thể biểu diễn thành dạng thập phân hữu hạn

hoặc vô hạn tuần hoàn, đến đây ta có thể thấy điều ngược lại không đúng

Từ công thức tìm được ở trên, ta có thể dễ dàng giải quyết được Câu 1

Gọi t là số chữ số của B

Trang 3

Như vậy là ta đã tìm được phân số biểu diễn số thập phân vô hạn tuần hoàn A,B(C)

Để giải quyết bài toán một cách trọn vẹn thì các bạn phải giải 2 trường hợp B = -1 và B

≠-1 Công thức ở trên mới chỉ giải trường hợp B≠-1 Đối với trường hợp B = -1, bằng cách làm tương tự như trên, ta có được công thức sau:

Còn một vấn đề cần giải quyết trước khi viết chương trình đó là: có trường hợp trong dạng biểu diễn của B,C có các chữ số 0 đứng đầu Như vậy nếu ta đọc B,C từ file với dạng số thì sẽ làm mất đi các chữ số 0 đứng đầu, vì thế sẽ làm sai lệch số chữ số của B,C

và khi thay vào công thức tính sẽ cho kết quả sai

Tôi đã giải quyết trường hợp này bằng cách đọc giá trị của B,C vào các xâu, sau đó chuyển xâu sang dạng số để giải Bằng cách này ta sẽ lưu được số chữ số thực của B,C Chương trình tôi viết cho hai câu trong bài này chỉ xử lí được các số trong phạm vi

longint Bạn nào muốn xử lí các số lớn hơn phải cài đặt các thuật toán xử lí số lớn Các

thuật toán này đã được giới thiệu trên các số báo trước Các bạn có thể tham khảo lại để cài đặt

Sau đây là chương trình cho Câu 1:

uses crt;

const fi='ThapPhan.inp';

fo='ThapPhan.out';

var a,b,c,nb,nc,p,q:longint;

xaub:string;

xauc:string;

{************************************************}

procedure nhap;

var f:text;

z:integer;

begin

assign(f,fi);

reset(f);

readln(f,a);

readln(f,xaub);

readln(f,xauc);

Trang 4

close(f);

val(xaub,b,z);

val(xauc,c,z);

end;

{************************************************} {Tìm ước chung lớn nhất của hai số nguyên dương a,b} function ucln(a,b:longint):longint;

var du:longint;

begin

ucln:=1;

if (a=1) or (b=1) then exit;

if a mod b=0 then begin ucln:=b; exit; end;

if b mod a=0 then begin ucln:=a; exit; end;

while b>0 do

begin

du:=a mod b;

a:=b;

b:=du;

end;

ucln:=a;

end;

{************************************************} {Tính 10a}

function mu10(a:longint):longint;

var i,tich:longint;

begin

tich:=1;

for i:=1 to a do

tich:=tich*10;

mu10:=tich;

end;

{************************************************} { Cho trường hợp B<>-1}

procedure xuli1;

begin

nb:=length(xaub);

nc:=length(xauc);

p:=a*mu10(nb)*mu10(nc)-a*mu10(nb)+b*mu10(nc)+c-b; q:=mu10(nb)*(mu10(nc)-1);

end;

{************************************************} { Cho trường hợp B=-1}

procedure xuli2;

begin

nc:=length(xauc);

p:=a*mu10(nc)+c-a;

Trang 5

q:=mu10(nc)-1;

end;

{************************************************}

procedure main;

var g:text;

d:longint;

begin

nhap;

if b=-1 then xuli2

else xuli1;

d:=ucln(p,q);

p:=p div d;

q:=q div d;

assign(g,fo);

rewrite(g);

writeln(g,p);

writeln(g,q);

close(g);

end;

{***********************************************}

BEGIN

clrscr;

main;

END

Bây giờ chúng ta sẽ giải quyết Câu 2

Trước hết ta thấy rằng theo định lí 1 và 2 dạng biểu diễn của phân số chỉ có thể là hữu

hạn hoặc vô hạn tuần hoàn Là hữu hạn hay vô hạn tuần hoàn phụ thuộc vào Q

Để giải quyết bài toán với các số nhỏ hơn ta đưa phân số về dạng tối giản

Ta có thể dễ dàng tìm được giá trị của A : A=P div Q

Lúc đó ta thay P=P mod Q Từ đây trở đi ta chỉ xét các phân số có tử nhỏ hơn mẫu Vì

vậy chỉ cần đi tìm B và C

Ta sẽ phân tích Q thành dạng: 2t*3k*5n*U (Với t,k,n,U là các số nguyên dương)

+ Trường hợp 1 Trong phân tích ra thừa số nguyên tố của Q chỉ chứa 2 và 5 mà không chứa bất kì số nguyên tố nào khác, tức là k=0 và U=1 (Q = 2t*5n)

Lúc này dạng biểu diễn của sẽ là hữu hạn hay có dạng 0,B

Để tìm được B ta làm như sau:

- Nếu t ≤ n ta đưa về dạng

Như vậy B=P*2n-t Gọi nb là số chữ số của B

Trang 6

Như vậy trong biễu diễn dạng số thập phân thì số chữ số 0 đứng liền sau dấu phẩy sẽ

bằng: n-nb

- Nếu t >n ta đưa về dạng

Như vậy B=P*5t-n Gọi nb là số chữ số của B

ị Trong biễu diễn dạng số thập phân thì số chữ số 0 đứng liền sau dấu phẩy sẽ bằng: t-nb.

+Trường hợp 2: Trong phân tích ra thừa số nguyên tố của Q có chứa các số nguyên tố

khác 2 và 5 Q có dạng 2t*3k*5n*U

Như vậy dạng biểu diễn của sẽ là vô hạn tuần hoàn hay có dạng 0,B(C)

Theo chứng minh ở trên ta phải đưa về dạng

(X là một số nguyên dương và có j chữ số 1

dưới mẫu)

Ta sẽ dùng một biến thương để lưu lượng phải nhân thêm vào P và Q để đưa được về

dạng , một biến mu10 để lưu số mũ của 10 trong biểu diễn của Q ở trên (cụ thể mu10 =i), một biến sl1 để lưu số chữ số 1 trong biểu diễn của Q (cụ thể sl1

=j)

Để đơn giản, ta sẽ loại bỏ khỏi Q phần chứa 2i*5i*9 sau khi nhân thêm với thương Khi

đó Q mới sẽ là ước của 111 11 (j số 1)

Cách làm như sau:

Khởi tạo thương=1 ; Q:=Q div 2 t *3 k *5 n

Lúc đầu thương, mu10 được tính như sau:

- Nếu t≤ n thì thương:= thương*2 n-t , mu10:=n

Ngược lại nếu t > n thì thương :=<i>thương*5t-n, mu10:=t

- Nếu k >2 thì Q:=Q*3 k-2

Vấn đề còn lại là đi tìm sl1 để 111 11 (có sl1 chữ số1, ta thay j ở trên bằng biến sl1) chia hết cho Q Theo định lí 2 thì sẽ luôn tìm được sl1

Ta sẽ dùng cách làm tương tự như cách đã làm ở bài 6, nhưng phải chú ý cập nhật

thương Tôi dùng cách làm này để các bạn có thể dễ dàng áp dụng khi cài đặt các thuật

toán xử lí số lớn

Thêm hai biến phu và thương10 có ý nghĩa sau:

phu để lưu thương của 111 11 khi chia cho Q

sẽ được cập nhật liên tục khi sl1 tăng lên

Thủ tục tìm sl1 sẽ như sau:

Chú ý: k trong thủ tục thay cho Q

Procedure so_luong_so_1(k:longint);

var du,du10,thuong10,phu:longint;

begin

sl1:=1;

Trang 7

if k=1 then exit;

phu:=0;

du:=1; du10:=1;

thuong10:=0;

repeat

inc(sl1);

thuong10:=thuong10*10+du10*10 div k;

du10:=du10*10 mod k;

phu:=phưthuong10+(dưdu10) div k;

du:= (dưdu10) mod k;

until du=0;

thuong:=thuong*phu;

end;

Biến du sẽ lưu số dư của 111 11 khi chia cho Q

Biến thương sẽ được tính lại là: thuong:=thuong*phu

Chương trình bị hạn chế bởi thương, thương10, phu là dạng longint nên chỉ chạy được với Q khá nhỏ Các bạn có thể bỏ các dòng lệnh chứa thương,thương10, phu để có thể tìm sl1 với Q lớn hơn

Còn một lưu ý nữa là: khi mu10 = 0 thì B = -1, do đó phải xử lý thêm trường hợp này Sau khi tìm được thương thì P:=P*thương

Để viết được dạng biểu diễn thập phân, chúng ta phải tìm được B và C Ta thấy rằng nếu

không tính các chữ số 0 đứng đầu thì số chữ số của B Ê mu10, số chữ số của C ≤ sl1

Theo trên P sẽ có dạng: B*(10sl1-1)+C

Từ đó ta sẽ duyệt toàn bộ các giá trị có thể có của B và C (với chú ý điều kiện về số chữ

số của B,C)

Sau khi tìm được B,C cách tính số chữ số 0 đứng đầu trong B,C các bạn có thể làm theo

cách đã giới thiệu ở trong trường hợp 1

Sau đây là chương trình cho câu 2:

uses crt;

const fi='Fraction.inp';

fo='Fraction.out';

var p,q,a,b,c,thuong:longint;

mu2,mu3,mu5,mu10,sl1:word;

f:text;

{************************************************}

procedure nhap;

begin

assign(f,fi);

reset(f);

readln(f,p,q);

close(f);

assign(f,fo);

rewrite(f);

end;

Trang 8

{************************************************}

{Tìm số mũ của số nguyên tố a trong dạng phân tích ra thừa số nguyên tố của So} function mu(a:word;var so:longint):word;

var k:word;

begin

k:=0;

while so mod a=0 do

begin

inc(k);

so:=so div a;

end;

mu:=k;

end;

{************************************************}

{Tìm ước chung lớn nhất của hai số nguyên dương a,b}

function ucln(a,b:longint):longint;

var du:longint;

begin

ucln:=1;

if (a=1) or (b=1) then exit;

if a mod b=0 then begin ucln:=b; exit; end;

if b mod a=0 then begin ucln:=a; exit; end;

while b>0 do

begin

du:=a mod b;

a:=b;

b:=du;

end;

ucln:=a;

end;

{************************************************}

{Tinh as }

function mu_as(a,s:word):longint;

var i,tich:longint;

begin

tich:=1;

for i:=1 to s do

tich:=tich*a;

mu_as:=tich;

end;

{************************************************}

{Tìm số chữ số cảu một số nguyên dương a}

function scs(a:longint):longint;

var k:longint;

begin

if a=0 then begin scs:=1; exit; end;

Trang 9

k:=0;

while a>0 do

begin

a:=a div 10;

inc(k);

end;

scs:=k;

end;

{************************************************} procedure huu_han;

var so,i:word;

begin

p:=p*thuong;

so:=scs(p);

if mu2>=mu5 then

begin

for i:=1 to mu2-so do write(f,0);

write(f,p);

end

else

begin

for i:=1 to mu5-so do write(f,0);

write(f,p);

end;

close(f);

halt;

end;

{***********************************************} procedure so_luong_so_1(k:longint);

var du,du10,thuong10,phu:longint;

begin

sl1:=1;

if k=1 then exit;

phu:=0;

du:=1; du10:=1;

thuong10:=0;

repeat

inc(sl1);

thuong10:=thuong10*10+du10*10 div k;

du10:=du10*10 mod k;

phu:=phưthuong10+(dưdu10) div k;

du:=(dưdu10) mod k;

until du=0;

thuong:=thuong*phu;

end;

{***********************************************}

Trang 10

procedure vo_han_tuan_hoan;

var phu,lim:longint;

begin

so_luong_so_1(q);

p:=p*thuong;

if mu10=0 then

begin

write(f,-1,' ');

for phu:=1 to sl1-scs(p) do write(f,0);

write(f,p);

close(f);

halt;

end;

phu:=mu_as(10,sl1)-1;

lim:=p div phu;

for b:=0 to lim do

if scs(b)<=mu10 then

begin

c:=p-b*phu;

if scs(c)<=sl1 then break;

end;

for phu:=1 to mu10-scs(b) do write(f,0);

write(f,b,' ');

for phu:=1 to sl1-scs(c) do write(f,0);

write(f,c);

close(f);

end;

{************************************************}

procedure xuli;

var d:longint;

begin

d:=ucln(p,q);

p:=p div d;

q:=q div d;

a:=p div q;

p:=p mod q;

write(f,a,' ');

mu2:= mu(2,q);

mu3:= mu(3,q);

mu5:= mu(5,q);

thuong:=1;

if mu2>=mu5 then begin thuong:=thuong*mu_as(5,mu2-mu5); mu10:=mu2; end else begin thuong:=thuong*mu_as(2,mu5-mu2); mu10:=mu5; end;

if (mu3=0) and (q=1) then huu_han;

if mu3<2 then thuong:=thuong*mu_as(3,2-mu3)

Trang 11

else if mu3>2 then q:=q*mu_as(3,mu3-2);

vo_han_tuan_hoan;

end;

{************************************************}

procedure main;

begin

nhap;

xuli;

end;

{************************************************}

BEGIN

clrscr;

main;

END

Trước khi kết thúc bài viết này, tôi muốn đưa ra cho các bạn một tính chất thú vị của số 7

về các số thập phân vô hạn tuần hoàn đó là:

Liệu còn số nào có tính chất như vậy không? Các bạn thử tìm xem

Nếu bạn nào cần chương trình nguồn của tất cả các bài đã nêu trên xin hãy liên hệ với tôi

Ngày đăng: 11/09/2012, 15:00

TỪ KHÓA LIÊN QUAN

TÀI LIỆU CÙNG NGƯỜI DÙNG

TÀI LIỆU LIÊN QUAN

w