/*
translation:
给出一个无限循环小数,把该小数改写成以最简分数表示的形式
solution:
如果能够求出分数的表示形式的话,那么利用gcd就可以化简。但是想了好久没有想出怎么化成分数形式。
后来百度"无限循环小数化分数",在百科上找到了答案。套用百科上的第三种公式即可。
note:
# 一开始样例都过不了,后来发现小数部分的下标范围出现错误。改下就过了。
* 写了两个版本,一种是利用c++的标准库函数来截取string类型,并利用atoi函数转换,另一种是自己编写的方法。
事实证明跟挂了一堆debug以及优化到极致的库函数比效率简直就是没事找事!以后遇到这种要处理字符串文本的一律使用
c++库函数!不过提交时候注意使用G++,用C++有时候会CE。
date:
2016.10.26
*/
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <limits>
#include <utility>
using namespace std;
const int maxn = 20;
typedef unsigned long long ull;
char str[maxn];
ull pow(ull a, ull n)
{
ull res = 1;
for(int i = 0; i < n; i++) res *= a;
return res;
}
ull gcd(ull a, ull b)
{
if(!b) return a;
return gcd(b, a%b);
}
ull getNum9(int len)
{
if(!len) return 0;
ull res = 1;
for(int i = 0; i < len; i++) res *= 10;
return res-1;
}
ull getNum(int s, int t)
{
ull res = 0;
for(int i = s; i < t; i++)
res = res * 10 + str[i] - '0';
return res;
}
//0.28...
int main()
{
//freopen("in.txt", "r", stdin);
while(cin >> str)
{
int len = strlen(str);
if(str[0] == '0' && len == 1) continue;
int s = 2, t = len-3; //为了防止出错,求出小数的范围,左闭右开
ull up = 0, down = 0; //首先当成纯循环小数
up = getNum(s, t); down = getNum9(t-s);
ull d = gcd(up, down);
up /= d; down /= d;
if(!up)
{
cout << "0/1" << endl;
continue;
}
ull n = getNum(s, t), n9 = getNum9(t-s);
for(int i = s+1; i < t; i++)
{
ull tmp_up = n - getNum(s, i);
ull tmp_down = n9 - getNum9(i-s);
d = gcd(tmp_down, tmp_up);
tmp_down /= d; tmp_up /= d;
if(tmp_down < down)
{
down = tmp_down;
up = tmp_up;
}
}
cout << up << "/" << down << endl;
}
return 0;
}
poj1930(无限循环小数化成分数)
最新推荐文章于 2019-11-03 16:02:30 发布