目录
题目描述
编写一个程序,输入一个形如N/D的分数,其中N是分子,D是分母,然后输出它的小数形式。如果小数用十进制表示有循环节,则把循环节放在一对圆括号中。例如,1/3=0.33333333······写成0.(3),41/333=0.123123123······写成0.(123)。用xxx.0表示整数。典型的转化例子:
1/3 = 0.(3)
22/5 = 4.4
1/7 = 0.(142857)
2/2 = 1.0
3/8 = 0.375
45/56 = 0.803(571428)
程序名
fracdec
输入格式
单独的一行有两个被空格分开的整数,N和D,1 <= N,D <= 100000。
输入样例
(文件 fracdec.in)
45 56
输出格式
如上所述的小数。如果结果长度大于76,每行输出76个字符。
输出样例
(文件 fracdec.out)
0.803(571428)
解题思路
第二章最后一题,短短的几行讲解,似乎挺简单。但仔细一想便发现要用高精度除法。其实这次有些变体,还没有一般的高精度难。创建两个数组a和m,a存每次除出来的小数,m用 m[余数]=所在位数 的方法存储每一步的余数。当遇上余数所在地址已存过位数时,则为循环节。
主要步骤
- 读入,初始化a[0]=n
- 进入 while 循环,在其中:1.求出余数 2.当前小数除以n 3.测试是否循环,如果循环了,记下循环节的头与尾 4.存储余数 5.下一位加上余数乘10 。然后循环往复,直至找出循环或除数等于0
- 输出,当输出到循环节的头时,输出“( ”,然后输出那一位小数,当输出到循环节的尾时,输出“ )”,每输出一个字符,就要记下来,当输出到76时,换行,重新计数
代码
/*
PROB:fracdec
LANG:C++
*/
#include <fstream>
#include <cstring>
using namespace std;
int n,d; //分子与分母
int a[100000]; //小数每一位
int m[100000]; //余数
int p,q; //循环节的头与尾
int i,j;
ifstream in("fracdec.in");
ofstream out("fracdec.out");
int main()
{
in>>n>>d;
a[0]=n;
memset(m,-1,sizeof(m));
int t=0; //小数计算的位数
do
{
int s=a[t]%d;
a[t]/=d;
if(m[s]!=-1)
{
p=m[s]+1;
q=t;
t++;
break;
} //测试是否循环
m[s]=t;
a[t+1]+=s*10;
t++;
}while(a[t]>0); //除数是否为0
out<<a[0]<<".";
j=1;
for(i=1;i<=100000;i*=10)
if(a[0]/i>0)
j++; //整数每多一位,字符数就加1
if(a[0]==0)
j++;
for(i=1;i<t;i++)
{
if(i==p)
{
out<<"(";
j++;
if(j==76)
{
out<<endl;
j=0;
}
}
out<<a[i];
j++;
if(j==76)
{
out<<endl;
j=0;
}
if(i==q)
{
out<<")"<<endl;
j=0;
break;
}
}
if(t==1)
out<<"0"<<endl;
if(j!=0&&t!=1)
out<<endl; //输出
in.close();
out.close();
return 0;
}