小数转分数
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1717
Problem Description
Ray 在数学课上听老师说,任何小数都能表示成分数的形式,他开始了化了起来,很快他就完成了,但他又想到一个问题,如何把一个循环小数化成分数呢?
请你写一个程序不但可以将普通小数化成最简分数,也可以把循环小数化成最简分数。
请你写一个程序不但可以将普通小数化成最简分数,也可以把循环小数化成最简分数。
Input
第一行是一个整数N,表示有多少组数据。
每组数据只有一个纯小数,也就是整数部分为0。小数的位数不超过9位,循环部分用()括起来。
每组数据只有一个纯小数,也就是整数部分为0。小数的位数不超过9位,循环部分用()括起来。
Output
对每一个对应的小数化成最简分数后输出,占一行。
Sample Input
3
0.(4)
0.5
0.32(692307)
Sample Output
4/9
1/2
17/52
思路:
1.对于不循环小数,小数位乘倍数,再除去倍数。例如, 0.351转化成,0.351 * 1000 / 1000, 即求351/1000,求gcd约分即可。
2.对于循环小数,利用循环小数的性质,x = 0.31(25),令m = 0.31(25) * 100 = 31.(25), n = 0.31(25) * 1000 = 3125.(25),即 (m - n) = x * (100 - 1000); x = (m - n) / (100 - 1000);求gcd约分
1 #include<stdio.h> 2 #include<string.h> 3 #define LL long long 4 5 char s[20]; 6 7 LL GCD(LL a, LL b)//求最大公约数 8 { 9 LL c; 10 while(b) 11 { 12 c = a % b; 13 a = b; 14 b = c; 15 } 16 return a; 17 } 18 19 int main() 20 { 21 int T; 22 scanf("%d", &T); 23 while(T --) 24 { 25 LL x = 0, y = 1; 26 int flag = 0, id; 27 scanf("%s", s); 28 int len = strlen(s); 29 for(int i = 2; i < len; i ++) 30 { 31 if(s[i] == '(') 32 { 33 flag = 1; 34 id = i; 35 break; 36 } 37 x = x * 10 + (s[i] - '0');//分子扩大多少 38 y *= 10;//分母就除去多少 39 } 40 if(flag == 0) //没有循环小数 41 { 42 LL temp = GCD(x, y); 43 printf("%lld/%lld\n", x / temp, y / temp); 44 } 45 else //有循环小数 利用循环小数的性质求解 46 { 47 LL xx = x, yy = y; 48 id ++; 49 for(int i = id; i < len; i ++) 50 { 51 if(s[i] == ')') 52 continue; 53 xx = xx * 10 + (s[i] - '0'); 54 yy *= 10; 55 } 56 LL a = xx - x; 57 LL b = yy - y; 58 LL temp = GCD(a, b); 59 printf("%lld/%lld\n", a / temp, b / temp); 60 } 61 } 62 return 0; 63 }