a除以b,其余数只有从0到b-1,共b种情况,模拟除法的过程,并记录商和余数出现的情况,当某个余数重复时,其间所得到商数列即为循环节。
用p[3010]记录得到的商,由于输入数据小于3000,用q[3010]记录余数出现情况:若在第i次循环中得到商n,则q[n] = i. 由于i从0开始,实际上使用q[n] = i+1.
这样,在每次得到一个余数k时,判断q[k]是否非0,若为0,令q[k] = i+1, 继续除法过程; 否则此即为循环节终点,q[k]原值为循环节起点,输出p[ q[k] ] ~ p[i]
循环节起点、终点坐标与循环次数i之间的关系可以手动模拟一次得到。
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
int main()
{
//freopen("input.txt","r",stdin);
int p[3010],q[3010],a,b,c,st,ed,i;
while(cin>>a>>b)
{
memset(p,0,sizeof(p));
memset(q,0,sizeof(q));
cout<<a<<'/'<<b<<" = "<<a/b<<'.';
i=0;
while(1){
p[i]=a/b,c=a%b;
if(q[c]){
st=q[c];
ed=i;
break;
}
else{
q[c]=i+1;
a=10*c;
}
i++;
}
for(i=1;i<=ed&&i<=50;i++){
if(i==st)
cout<<'(';
cout<<p[i];
}
if(ed>50)
cout<<"...";
cout<<')'<<endl;
cout<<" "<<ed-st+1<<" = number of digits in repeating cycle"<<endl<<endl;
}
return 0;
}