poj1930(无限循环小数化成分数)

/*
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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值