HDU1717 小数化分数2

    该题要求将小数通通化为分数,这个过程是一个纯数学运算,大概是小学的奥赛题吧。。哇哇。。。。

如果是普通分数,好说,就是同乘以10^x次方的数,再约分就可以了。 

例如 0.234  -->  234/1000   -->    117/500

如果是纯循环小数,那么就要借助方程来解了。

例如 0.(1234)   令x= 0.(1234), 对这个循环小数有 10000x- x= 1234, 解出来 x= 1234/9999, 在约分就行了 这里等于 1234/9999

如果是这种情况呢 0.24(765)  可以很清楚的认识到,这是前两者的综合版,分开算再通分,约分......  这里还是借助方程来解。

例如 0.24(765)  令x= 0.24(765), 100000x- 100x= 765- 24, 解出来 x=  2749/11100。

代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <time.h>
#include <ctype.h>

char num[20];

int gcd( int x, int y )
{
    while( x )
    {
        int c= x;
        x= y% x;
        y= c;
    }
    return y;
}

int getmo( int len1, int len2 )
{
    int sum= 9;
    for( int i= 2; i<= len2; ++i )
    {
        sum= sum* 10+ 9;
    }
    for( int i= 1; i<= len1; ++i )
    {
        sum*= 10;
    }
    return sum;
}

int _pow( int x )
{
    int sum= 1;
    for( int i= 1; i<= x; ++i )
    {
        sum*= 10;
    }
    return sum;
}
int getson( int sp, int so )
{
    return sp- so;
}

int main()
{
    int N;
    scanf( "%d", &N );
    
    while( N-- )
    {
        int so, sp, len, len1, len2, point, son, mo;
        scanf( "%s", num );
        len= strlen( num );
        if( num[len- 1]!= ')' )
        { 
            mo= _pow( len- 2 );
            son= atoi( num+ 2 );
            int e= gcd( son, mo ); // 得到最大约数 
            printf( "%d/%d\n", son/ e, mo/ e );
            continue;
        }
        num[len- 1]= '\0';
        point= strchr( num, '(' )- num;
        len1= point- 2;  // 非循环串长度 
        len2= strlen( num+ point+ 1 );  // 循环串长度 
        mo= getmo( len1, len2 );  // 得到分母 
        so= atoi( num+ 2 );
        sp= atoi( num+ point+ 1 );  // 将循环串与非循环串转化为数字 
        sp= so* _pow( len2 )+ sp;
        son= getson( sp, so );
        int e= gcd( son, mo );
        printf( "%d/%d\n", son/ e, mo/ e ); 
    }
    return 0;
}
原文地址:https://www.cnblogs.com/Lyush/p/2108761.html