您的位置:首页 > 其它

[USACO2.4]分数化小数 Fractions to Decimals

2017-07-31 17:44 411 查看


题目描述

写一个程序,输入一个形如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)
PROGRAM NAME fracdec


输入输出格式

输入格式:

单独的一行包括被空格分开的N和D(1 <= N,D <= 100000)。

输出格式:

按照上面规则计算出的小数表达式.如果结果长度大于76,每行输出76个字符.


输入输出样例

输入样例#1:
45 56


输出样例#1:
0.803(571428)



说明

翻译来自NOCOW

USACO 2.4
【题解】

/*
ID:luojiny1
LANG:C++
TASK:fracdec
*/
#include<cstdio>
#include<cstring>
const int maxn=100010;
bool done[maxn]={0};//不难证明对于每一个余数(将来会成为新的被除数)如果重复,则是循环节。但是商的小数部分重复却不一定
int p[maxn],ans[maxn],N,D;//p指向每次除法时余数所对应的答案(编号),ans为小数部分;
int cur=3;
void solve(int num)//输出优化 计算出偏移量 比如10.  是占位置的 %64输出需要注意
{
int t=10;
while(t<=num){
t*=10;
cur++;
}
}

int main()
{
freopen("fracdec.in","r",stdin);
freopen("fracdec.out","w",stdout);
memset(p,-1,sizeof(p));
scanf("%d%d",&N,&D);
if(N%D==0)printf("%.1f\n",(float)N/D);//特殊情况
else{
solve(N/D);
printf("%d.",N/D);
int a=N%D,n=0;
while(done[a]==0){
if(a==0){//整除的情况下
for(int i=0;i<n;i++)printf("%d",ans[i]);
printf("\n");
return 0;
}
done[a]=1;//余数(将来的被除数)  决策
p[a]=n;//更新指向
ans[n++]=a*10/D;//成为被除数
a=(a*10)%D;//成为余数
}
for(int i=0;i<p[a];i++){//输出
printf("%d",ans[i]);
if((i+1+cur)%76==0)putchar('\n');
}
putchar('(');
for(int i=p[a];i<n;i++){
printf("%d",ans[i]);
if((i+1+cur)%76==0)putchar('\n');
}
printf(")\n");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: