USACO 2.4 fracdec (Fractions to Decimals)

目录

题目描述

编写一个程序,输入一个形如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[余数]=所在位数 的方法存储每一步的余数。当遇上余数所在地址已存过位数时,则为循环节。

主要步骤

  1. 读入,初始化a[0]=n
  2. 进入 while 循环,在其中:1.求出余数 2.当前小数除以n 3.测试是否循环,如果循环了,记下循环节的头与尾 4.存储余数 5.下一位加上余数乘10 。然后循环往复,直至找出循环或除数等于0
  3. 输出,当输出到循环节的头时,输出“( ”,然后输出那一位小数,当输出到循环节的尾时,输出“ )”,每输出一个字符,就要记下来,当输出到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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值