输入整数a和b(0≤a≤3000,1≤b≤3000),输出a/b的循环小数表示以及循环节长度。例
如a=5,b=43,小数表示为0.(116279069767441860465),循环节长度为21。
思路:这道题的关键思路 是模拟竖式计算除法的过程:求小数部分时,每次都是将得到的余数*10再除以除数,记录每次得到的商和余数,直到得到的商和余数在前面出现过,说明此时开始循环。另外,如果余数为0,说明是除尽了。
/*习题3-8 循环小数(Repeating Decimals, ACM/ICPC World Finals 1990, UVa202)*/
#include
#include
#define maxn 3000
int mod_in(int mod[],int res[],int m,int yu,int sh)
{
for(int i=0;i
return i;
return -1;
}
int main()
{
int a,b;
while(scanf("%d %d",&a,&b)!=EOF)
{
int res[maxn],mod[maxn],index[maxn];
memset(res,0,sizeof(res));
memset(mod,0,sizeof(mod));
memset(index,0,sizeof(index));
int t = a,n=0;
//先将整数商部分与除数相乘的结果从被除数中减掉,*10开始小数部分的计算
t = (a-a/b*b)*10;
int loc;
while(1)
{
res[n] = t/b;
mod[n] = t%b;
loc = mod_in(mod,res,n,mod[n],res[n]);
if(loc!=-1)
break;
index[mod[n]] = 1;
t = t%b*10;
n++;
}
// printf("res ");
// for(int i=0;i<=n;i++)
// printf("%d ",res[i]);
// printf("\nmod ");
// for(int i=0;i<=n;i++)
// printf("%d ",mod[i]);
// printf("\n");
printf("%d/%d = %d.",a,b,a/b);
//除尽了
if(mod[n]==0)
{
if(loc>0)
{
for(int i=0;i
}
printf("(0)");
}
else if(n<50)
{
for(int i=0;i
printf("(");
for(int i=loc;i
printf(")");
}
else
{
for(int i=0;i
printf("(");
for(int i=loc;i<50;i++)
printf("%d",res[i]);
printf("...)");
}
printf("\n %d = number of digits in repeating cycle\n\n",n-loc);
}
}