HDU 1717 - 小数化分数2

18 篇文章 0 订阅

整数化小数,不循环的小数容易化。对于循环小数化分数原理如下:

⑴    把0.4747……和0.33……化成分数。
例1:        0.4747……×100=47.4747……   
0.4747……×100-0.4747……=47.4747……-0.4747……
(100-1)×0.4747……=47
即99×0.4747…… =47 
那么  0.4747……=47/99
例2: 0.33……×10=3.33……
0.33……×10-0.33……=3.33…-0.33……
 (10-1) ×0.33……=3
即9×0.33……=3
 那么0.33……=3/9=1/3

由此可见, 纯循环小数化分数,它的小数部分可以写成这样的分数:纯循环小数的循环节最少位数是几,分母就是由几个9组成的数;分子是纯循环小数中一个循环节组成的数。
⑵把0.4777……和0.325656……化成分数。
例1:0.4777……×10=4.777……①
0.4777……×100=47.77……②
用②-①即得: 
0.4777……×90=47-4
所以, 0.4777……=43/90
例2:0.325656……×100=32.5656……①
0.325656……×10000=3256.56……②
用②-①即得: 
0.325656……×9900=3256.5656……-32.5656……
0.325656……×9900=3256-32
所以, 0.325656……=3224/9900
根据原理,易写出代码。
代码如下:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
using namespace std;
int gcd(int a, int b)
{
    return b == 0 ? a : gcd(b, a%b);
}
int main()
{
#ifdef test
    freopen("sample.txt", "r", stdin);
#endif
    int t, num_1, num_2;
    char str[22], str_1[11], str_2[11];
    scanf("%d", &t);
    while(t--)
    {
        int i, Gcd;
        int len_1=0, len_2=0;
        scanf("%s", str);
        for(i=2; str[i]!='(' && str[i]!='\0'; i++)
            str_1[len_1++] = str[i]; // 小数不循环部分存储
        for(; str[i]!=')' && str[i]!='\0'; i++)
            if(str[i] != '(')
                str_2[len_2++] = str[i]; // 小数循环部分存储
        str_1[len_1] = str_2[len_2] = '\0';
        if(!len_2) // 没有循环小数情况
        {
            int beishu = 1;
            for(int i=0; i<len_1; i++)
                beishu *= 10;
            sscanf(str_1, "%d", &num_1);
            Gcd = gcd(num_1, beishu);

            printf("%d/%d\n", num_1/Gcd, beishu/Gcd);
        }
        else // 有循环小数情况
        {
            int bei1 = 1, bei2 = 1;
            str[0]=0;
            sprintf(str, "%s%s", str_1, str_2);
            sscanf(str, "%d", &num_2);
            if(len_1)
                sscanf(str_1, "%d", &num_1);
            else
                num_1=0;
            for(int i=0; i<len_1; i++)
                bei1 *= 10;
            for(int i=0; i<len_2+len_1; i++)
                bei2 *= 10;
            Gcd = gcd(num_2-num_1, bei2-bei1);
            printf("%d/%d\n", (num_2-num_1)/Gcd, (bei2-bei1)/Gcd);
        }
        //printf("&& %d\n", (32692307-32)/gcd(32692307-32, 100000000-100));
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值