PDA

View Full Version : Số thập phân vô hạn tuần hoàn...



lehuukyquan
13-03-2009, 15:02
Vô tình mình được 1 bạn "đày đọa nhẹ nhàng" bằng cái đề như sau:
input: m,n số nguyên
Output: m/n có phải là thập phân vô hạn tuần hoàn k? Biểu diễn chúng
Ví dụ 4/3=1.333=1.(3) thì phải...

program TPVHTH;
uses crt;
var a:array [1..100] of longint;
n,m,k1,t1,k:longint;
kt:boolean;
s,s1,ss:string;
kq:real;
procedure process;
var i:integer;
begin
i:=1;
repeat
if n>=m then
begin
a[i]:=n div m;
n:=n-(a[i]*m);
inc(i);
end
else
begin
a[i]:=0;
inc(i);
end;
n:=n*10;
until (i=11)or(n=0);
end;
procedure tinh;
var i,k:integer;
begin
i:=0; kt:=true;
repeat
for k:=t1 to t1+1 do
begin
str(a[k],s1);
ss:=ss+s1;
inc(i);
if s[i]<>s1 then kt:=false;
end;
s:=ss;
ss:='';
i:=0;
t1:=t1+k1;
until (kt=false)or(k=10-k1+1);
if kt then write('Thuong La So Thap Phan Vo Han Tuan Hoan')
else write('Khong La So Thap Phan Vo Han Tuan Hoan');
end;
procedure xuli1;
var t,i:integer; s1:string;
begin
t:=a[10]; str(a[10],s1);
s:=s+s1;
for i:=10 downto 2 do
if t<>a[i] then
begin
str(a[i],s1);
s:=s+s1;
end
else
break;
k1:=length(s); kt:=true;
if k1=1 then
begin
for k:=10 downto 6 do
begin
str(a[k],s1);
if s[k1]<>s1 then kt:=false;
end;
end;
if kt=false then
begin
s1:='';
s:='';
end;
end;
procedure xuli2;
var t,i:integer;
begin
t:=a[2]; str(a[2],s1);
s:=s+s1;
for i:=3 to 10 do
if t<>a[i] then
begin
str(a[i],s1);
s:=s+s1;
end
else
break;
k1:=length(s);
t1:=k1+2;
tinh;
end;

begin
clrscr;
write('Nhap n =');readln(n);
write('Nhap m =');readln(m);
if n mod m =0 then write('Thuong Khong Phai So Thap Phan Vo Han Tuan Hoan')
else
begin
process;
xuli1;
if kt then write('Thuong La So Thap Phan Vo Han Tuan Hoan')
else
xuli2;
end;
readln;
end.

Mình sử dụng cách ăn gian lận thôi, bài này mà test full thì thua chắc rồi, các bạn sửa lại dùm và cho dùm phân tích nhé...
Thanh kìu mẹt xi vé ri nhiều!

hang_vt
20-03-2009, 20:05
const fi='phepchia.inp';
fo='phepchia.out';
max=1000000;
var f:text;
n,k,i,j:longint;
a,b:array[0..max] of longint;
procedure inp;
begin
assign(f,fi);
reset(f);
readln(f,n,k);
close(f);
end;
procedure test;
begin
a[0]:=n mod k;
b[0]:=n div k;
for i:=1 to max do
begin
a[i]:=(a[i-1]*10) mod k;
b[i]:=(a[i-1]*10) div k;
for j:=0 to i-1 do
if a[j]=a[i] then
begin
exit;
end;
end;
if i=max then j:=i;
end;
procedure pri;
var h,k:longint;
begin
assign(f,fo);
rewrite(f);
write(f,b[0]);
if a[0]<>0 then write(f,'.')
else
begin
close(f);
exit;
end;
for h:=1 to j do write(f,b[h]);
if (a[j]=0) or (i=j) then
begin
close(f);
exit;
end;
if i<250 then write(f,'(');
for h:=j+1 to i do
begin
write(f,b[h]);
if h>250 then
begin
close(f);
exit;
end;
end;
write(f,')');
close(f);
end;
begin
inp;
test;
pri;
end.

xem ra thì hem ai bàn luận về bài này ........

huysun
21-03-2009, 11:30
Vô tình mình được 1 bạn "đày đọa nhẹ nhàng" bằng cái đề như sau:
input: m,n số nguyên
Output: m/n có phải là thập phân vô hạn tuần hoàn k? Biểu diễn chúng
Ví dụ 4/3=1.333=1.(3) thì phải...

nếu m chia hết cho n thì không phải.
tìm tất cả ước của n, nếu chỉ có 2 và 5 thì cũng không phải.
nếu là phải, biểu diễn m/n thành 1 xâu rồi dùng hàm pos để tìm phần lặp lại(theo kiểu vét cạn, nhưng khi tìm được rồi thì thôi).

hang_vt
21-03-2009, 13:05
nếu m chia hết cho n thì không phải.
tìm tất cả ước của n, nếu chỉ có 2 và 5 thì cũng không phải.
nếu là phải, biểu diễn m/n thành 1 xâu rồi dùng hàm pos để tìm phần lặp lại(theo kiểu vét cạn, nhưng khi tìm được rồi thì thôi).
- n lên tới 10^6 , vét k tối ưu lắm
- đính chính đề 1 tí : hãy thực hiện fép chia n cho m ( kết quả biểu diễn ở hệ thập fân hữu hạn hoặc vô hạn tuần hoàn , nếu k tuần hoàn thì in ra 250 số fần thập fân )
vd: inp
5 7
out
0.(714285)

bld
21-03-2009, 21:36
bài hay lắm , nhưng mình không quen thao tác với mấy con số real,
nhưng thuật toán như trên chắc là okie rồi