HDU ACM Steps:小数化分数2

HDU ACM Steps:小数化分数2

题目描述

Ray 在数学课上听老师说,任何小数都能表示成分数的形式,他开始了化了起来,很快他就完成了,但他又想到一个问题,如何把一个循环小数化成分数呢?
请你写一个程序不但可以将普通小数化成最简分数,也可以把循环小数化成最简分数。

输入

第一行是一个整数N,表示有多少组数据。
每组数据只有一个纯小数,也就是整数部分为0。小数的位数不超过9位,循环部分用()括起来。

输出

对每一个对应的小数化成最简分数后输出,占一行。

输入样例

3
0.(4)
0.5
0.32(692307)

输出样例

4/9
1/2
17/52

思路

1.对于普通小数,只需要将分母变为 1 0 n 10^n 的形式,然后分子分母约分(都除以最大公约数)。

2.对于纯循环小数:只需要将循环部分除以{9、99、999、……}中对应的数即可(循环部分的长度和9的个数相同)。例如:0.(4)=4/9;0.(34)=34/99;
证明
0. ( 4 ) × 10 0. ( 4 ) = 4 0.(4)\times10-0.(4)=4
0. ( 4 ) × 9 = 4 0.(4)\times 9=4
0. ( 4 ) = 4 / 9 0.(4)=4/9

3.对于形如0.32(692307)的混合小数,将其分为普通小数和循环小数两个部分。
0.32 ( 692307 ) = 0.32 + 0. ( 692307 ) × 100 0.32(692307)=0.32+0.(692307)\times 100
再分别求得两个分数,再同分求和。

代码

#include<stdio.h>
#include<math.h>
typedef long long ll;

int n;
char num[20];
ll x,y;        // x/y    非循环部分
ll a,b,c;     //  a/b    循环部分 

ll gcd(ll x,ll y)
{
     return y ? gcd(y,x%y) : x;
}

int main()
{
	scanf("%d",&n);
	while(n--)
	{
		int i;
		a=0,b=0,x=0,y=1;
		scanf("%s",num);
		
		for(i=2;num[i]<='9'&&num[i]>='0';i++)
		{
			x=x*10+num[i]-'0';
			y*=10;
		}
		if(num[i]!='\0')//循环部分 
		{
			for(i++;num[i]<='9'&&num[i]>='0';i++)
			{
				a=a*10+num[i]-'0';
			    b=10*b+9;
			}
		}
		
		
		if(a)//此时有循环部分,通分求和
		{
			x=x*b+a;
			y=b*y;
		}
		
		c=gcd(x,y);//约分
		x=x/c;
		y=y/c;
		
		printf("%ld/%ld\n",x,y);
		
	}
	return 0;
 }
发布了13 篇原创文章 · 获赞 2 · 访问量 338

猜你喜欢

转载自blog.csdn.net/weixin_45718149/article/details/104640781