Tải bản đầy đủ (.doc) (11 trang)

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

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (218.1 KB, 11 trang )

ứ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
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.
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);
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 10
a
}
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;
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: 2
t
*3

k
*5
n
*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 = 2
t
*5
n
)
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*2
n-t
. Gọi nb là số chữ số của B.
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:

×