标签:
Description
Input
Output
Sample Input
Sample Output
假如设小数点后的整数记为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 = val2 / 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; }
标签:
原文地址:http://www.cnblogs.com/andyqsmart/p/4526527.html