ACM学习历程—HDU1717 小数化分数2(gcd)
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
假如设小数点后的整数记为val1,括号里循环的整数记为val2。
val1的位数记为len1,val2的位数记为len2。
记小数的不循环部分是e1, 循环部分是e2.
对于e2 * 10^len1这个小数t:
必然t * 10^len2 - val2 = t;
自然t = val2 / (10^len2 - 1)
e2 = val2 / (10^len2 - 1) / 10^len1;
然后e1 = val1 / 10^len1;
所以整个小数就是e1 + e2;
然后对分子分母同分一下,最后分子分母再同除最小公倍数即可。
需要注意的是要对len2等于0的情况特判一下。
代码:
#include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <algorithm> #include <set> #include <map> #include <vector> #include <queue> #include <string> #define LL long long using namespace std; LL e[11], val1, val2, A, B; int len1, len2; char str[50]; void Init() { e[0] = 1; for (int i = 1; i < 11; ++i) { e[i] = 10*e[i-1]; } } void Input() { scanf("%s", str); len1 = len2 = 0; val1 = val2 = 0; for (int i = 2; str[i] != '\0'; ++i) { if (str[i] == '(') { for (int j = i+1; str[j] != ')'; ++j) { val2 = 10*val2 + str[j] - '0'; len2++; } break; } val1 = 10*val1 + str[i] - '0'; len1++; } if (len2) { A = val1*(e[len2] - 1) + val2; B = e[len1] * (e[len2]-1); } else { A = val1; B = e[len1]; } } LL gcd(LL a, LL b) { if (b == 0) return a; else return gcd(b, a%b); } void Work() { LL d = gcd(A, B); A /= d; B /= d; printf("%I64d/%I64d\n", A, B); } int main() { //freopen("test.in", "r", stdin); int T; scanf("%d", &T); Init(); for (int times = 0; times < T; ++times) { Input(); Work(); } return 0; }
把每一道题当作难题去做。
posted on 2015-05-24 21:31 AndyQsmart 阅读(462) 评论(0) 编辑 收藏 举报