HDU-1717 小数化分数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; }