(水)POJ-1930 无限循环小数化分数

本文介绍了将无限循环小数转换为最简分数的方法,包括纯循环小数和混循环小数的转换公式,并提供了C++实现代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目大意:赶论文:论文里无限循环小数到底是由哪两个数除出来的呢?求分母最小的那一对。


题目链接:点击打开链接


分析:其实重点就在如何将无限循环小数化为分数,这里给大家归纳了公式。然后枚举循环节找出最小分母就行。

纯循环小数

用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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值