题目来源:http://116.56.140.75:8000/JudgeOnline/problem.php?id=1730
1730: 小数化分数
时间限制: 1 Sec 内存限制: 64 MB题目描述
在计算机中。使用float或double来存储小数,但其缺点是得不到精确值。如果,我们希望得到精确计算结果,最好用分数形势来表示小数。有限小数或无限小数都可以转化为分数。比如: 0.9 = 9/10 0.333(3) = 1/3 (括号中的数字表示是循环节) 当然,一个小数可以用好几种分数形式来表示。如: 0.333(3) = 1/3 = 3/9 给定一个有限小数或无限循环小数,你能否以分母最小的分数形式来返回这个小数呢?如果输入为循环小数,循环节用括号标记出来。如: 0.3、0.30、0.3(000)、0.3333(3333)、……
输入
输入数据将有多组测试样例,首先输入一个正整数T,表示有T组测试样例。接下来有T行输入,每行输入一个小数d( d < 1 ,有限小数的位长小于等于6,无限循环小数的循环节用一对括号标记,且其非循环部分的位长小于等于6、循环节的位长小于等于6 )。
输出
对于每组测试样例,要求输出由小数对应的分母最小的分数,其格式为“分子/分母”,相邻的结果间用一个回车分隔。
样例输入
3
0.9
0.111(1)
0.(9)
样例输出
9/10
1/9
1/1
解析:注意0和无限循环小数的处理
代码:
#include<iostream>
#include<cmath>
#include<string>
using namespace std;
long long int gcd(long long int a, long long int b)
{
if (a == 0)
return b;
else
return gcd(b%a, a);
}
int main()
{
int t;
cin >> t;
while (t--)
{
string str;
cin >> str;
int num = str.size();
long long int m = 0, n = 0;
if (num == 1)
cout << 0 << endl;
else
{
if (str[num - 1] != ')')
{
for (int i = num - 1; i > 1; i--)
m += ((str[i] - '0')*pow(10, num - 1 - i));
n = pow(10, num - 2);
}
else
{
if (str[2] == '(')
{
for (int i = num - 2; i > 2; i--)
m += ((str[i] - '0')*pow(10, num - 2 - i));
n = pow(10, num - 4) - 1;
}
else
{
int k = num - 2;
for (; k > 1; k--)
{
if (str[k] == '(')
break;
}
long long int m1 = 0;
for (int j = k - 1; j > 1; j--)
m1 += ((str[j] - '0')*pow(10, k - 1 - j));
for (int j = num - 2; j > k; j--)
m += ((str[j] - '0')*pow(10, num - 2 - j));
for (int j = k - 1; j > 1; j--)
m += ((str[j] - '0')*pow(10, num - j - 3));
m -= m1;
n = pow(10, num - 4) - pow(10, k - 2);
}
}
long long int g = gcd(m, n);
m /= g;
n /= g;
if (m == 0)
cout << 0 << endl;
else
cout << m << "/" << n << endl;
}
}
}
/**************************************************************
Problem: 1730
User: 201730685257
Language: C++
Result: 正确
Time:0 ms
Memory:1496 kb
****************************************************************/