题目大意:赶论文:论文里无限循环小数到底是由哪两个数除出来的呢?求分母最小的那一对。
题目链接:点击打开链接
分析:其实重点就在如何将无限循环小数化为分数,这里给大家归纳了公式。然后枚举循环节找出最小分母就行。
纯循环小数
用9做分母,有多少个循环数就几个9,比如0.3,3的循环就是9分之3,0.654,654的循环就是999分之654, 0.9,9的循环就是9分之9(1),以此类推。
len = 循环节长度
a = 循环节对应的整数(如0.654对应654)
公式:
分子 = a
分母 = pow(10,len)-1
混循环小数
先来看几个例子
例:把混循环小数0.228˙化为分数:
解:0.228˙
=[(228/1000)+8/9000)]
=228/(900+100)+8/9000
=[(228/900)-(228/9000)]+(8/9000)
=(228/900)+[(8/9000)-(228/9000)]
=(228/900)-(22/900)
=(228-22)/900
=206/900
=103/450;
例:把混循环小数0.123˙68˙化成分数:
解:0.123˙68˙=(0.12368+0.00000˙68˙)
=(12368/100000)+(68/9900000)
=[(12368/99000)-(12368/990000)]+(68/9900000)
=(12368/99000)+[(68/9900000)-(12368/9900000)]
=(12368/99000)-(12300/9900000)
=(12368-123)/99000
len = 非循环部分长度
Len = 非循环部分长度(len)+循环节长度(如0.123˙68˙的Len=3+2)
a = 非循环部分对应整数(如0.123˙68˙对应a为123)
A = 非循环部分+循环节对应整数(如0.123˙68˙对应A为12368)
公式:
分子 = A-a
分母 = pow(10,Len)-pow(10,len)
然后纯循环小数可以看成a为0,len为0来利用混循环小数的公式计算,免得搞真搞混了!
附上代码:
#include <iostream>
#include <string>
#include <limits>
using namespace std;
typedef unsigned long long ULL;
ULL gcd(ULL a, ULL b)
{
if (b == 0)return a;
return gcd(b, a%b);
}
ULL ten_pow(unsigned int x)
{
ULL result = 1;
for (unsigned int i = 0; i < x; ++i)
{
result *= 10;
}
return result;
}
int main()
{
string line;
while (cin >> line)
{
if (line == "0")
{
break;
}
string digit = line.substr(2, line.length() - 5);
unsigned int length = digit.length();
const ULL n = atoi(digit.c_str());
if (n == 0)
{
cout << "0/1" << endl;
continue;
}
ULL min_x = numeric_limits<ULL>::max();
ULL min_y = 0;
for (int i = 1; i <= length; ++i)
{
string first = digit.substr(0, length - i);
ULL x = ten_pow(length) - ten_pow(length - i);
ULL y = n - atoi(first.c_str());
ULL d = gcd(x, y);
x /= d;
y /= d;
if (min_x > x)
{
min_x = x;
min_y = y;
}
}
cout << min_y << '/' << min_x << endl;
}
return 0;
}