1439: 2.4.5 Fractions to Decimals 分数化小数
Time Limit: 1 Sec Memory Limit: 64 MBSubmit: 335 Solved: 75
[ Submit][ Status][ Web Board]
Description
写一个程序,输入一个形如N/D的分数(N是分子,D是分母),输出它的小数形式。 如果小数有循环节的话,把循环节放在一对圆括号中。例如, 1/3 = .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)Input
单独的一行包括被空格分开的 N和D, 1 <= N,D <= 100000。Output
小数的表示方法上面说的很明白了,如果输出的长度超过76个字符,每行输出76个。Sample Input
45 56
Sample Output
0.803(571428)
HINT
Source
分析:看着和数学有关,其实是一道大模拟......细节非常多:
1.因为要76行一输出,所以要先用一个变量记录长度,小数点也要加上去.
2.如果能够除尽,直接输出答案即可.
3.对于整数部分的长度,不断除以10,直到等于0,每次除的时候累加长度.
4.如果除以10恰好等于0,那么长度+1.
然后就是小数部分的处理了,难点是循环节的处理,如果一个余数之前恰好出现过,而当前的除数正好是之前余数对应的除数,那么就出现循环节,这里用两个数组记录,一个记录上一个相同余数位置,一个记录除数.
最后输出的时候判断累加的长度是否为76,是则换行即可.
#include<stdio.h>
#include<iostream>
#include<algorithm>
using namespace std;
#define maxn 1000120
int n,d;
int cur[maxn],h[maxn];
int remainder1[maxn],integer[maxn];//存储余数,除数
int tot1=1,tot,l,r;
int main()
{
scanf("%d%d",&n,&d);
if(n%d==0)
{
printf("%d.0\n",n/d);
return 0;
}
printf("%d.",n/d);
int temp=n/d;
while(temp)
{
tot1++;
temp/=10;
}
if(n/d==0)
tot1++;
remainder1[0]=n%d;
while(1)
{
tot++;
integer[tot]=remainder1[tot-1]*10/d;
remainder1[tot]=remainder1[tot-1]*10%d;
if(cur[remainder1[tot]]>0&&h[cur[remainder1[tot]]]==integer[tot])
{
l=cur[remainder1[tot]];
r=tot-1;
break;
}
cur[remainder1[tot]]=tot;//记录余数的位置
h[cur[remainder1[tot]]]=integer[tot];//记录在此位置的除数
}
for (int i = 1; i <= tot; i++)
{
if (i == l)
{
printf("(");
tot1++;
}
printf("%d",integer[i]);
tot1++;
if (i == r)
{
printf(")");
break;
}
if (tot1 % 76 == 0)
printf("\n");
}
printf("\n");
}