求助!1道NOIP初赛模拟试题

来源:百度知道 编辑:UC知道 时间:2024/09/21 08:50:08
pascal的
循环小数
题目描述:给出一个分数的分子和分母,要将其转换为小数的形式。
输入:只有两个整数,分别表示分数的分子和分母。
输出:只有一个十进制小数,表示这个分数转换成的小数。如果得到的小数不是循环小数,则输出其全部数字。否则在输出完毕第一个循环节后不再输出。
program fill1;
var
s,t:array[0..99]of longint;
a,b,g,i,j,d:longint;
function gcd(a:longint;b:longint):longint;
begin
if b=0 then gcd:=a
else gcd:=①;
end;
procedure work(a:longint;b:longint);
begin
i:=0;
d:=1;
while true do
begin
if a=0 then break;
a:=a*10;
t:=a;
s:=a div b;
a:=a mod b;
for j:=0 to i-1 do
if (s[j]=s)and(t[j]=t) then
begin
dec(d);
②;
end;
if d=0 then break;
write(s);
③;
end;
end;
begin
read(a,b);
if (a>b) then g:=gcd(a,b)
else ④;
a:=a div g;
b:=b div g;
⑤;
a:=a mod b;
work(a,b);
end.
本人

这题首先有个错误
s,t:array[0..99]of longint; 且函数无特殊定义
s:=a div b; 't'也有同样错误(为了方便姑且设这个'S'为's1',‘t'为't1')
做阅读程序题时,先看主程序
a:=a div g;
b:=b div g;
说明g用于约分,所以gcd应当是求a,b最大公约数的程序
gcd是经典的辗转相除法经典程序,故①填 gcd(b,a mod b)
由于辗转相除法对于两个数大小关系有严格要求
if (a>b) then g:=gcd(a,b) 就是判断大小关系
所以④ g:=gcd(b,a)
约分后要将假分数化成真分数
⑤ if a mod b=0 then write (a div b) else write(a div b,'.')(若本身为真分数,则为零,if用于判断是否是整数,要不要小数点)
在work中
由 a:=a mod b; 看出a储存余数
由 s:=a div b; 看出s1储存商的目前位数(为避免矛盾S改为S1)
(s[j]=s)and(t[j]=t) 表示 被除数和商与以前的某次运算相同,即当前商是循环小数的第二个循环节的第一位
dec(d) 和 if d=0 then break; 即退出循环的
因为 要 记录每次求得商和余数方便寻找循环节并增加商位数,所以
③ s[i]:=s1;t[i]:=t1;inc(i)
至于② 按照题目要求其实不填也可以 ,为了填上就 ② exit 吧
当然如果循环节要输出第二个首位可以在这里输出,
当然如果要标识出循环节,也许会填,但这个程序基本无法达到
这种题最好有范例输出