题解 P2399 【non hates math】

这题其实不难,只要注意细节即可

公式:

有限小数(记小数位数为n):小数整个儿做分子,分母是10^n

纯循环小数(记小数位数为n):小数整个儿做分子,分母是999……9(共有n个9)

混循环小数(记循环节位数为n1,非循环节位数为n2):分子等于非循环节的数和循环节的数组合起来,再减去非循环节的数,分母是99……900……0(n1个9,n2个0)

例如:

(1) 0.12345=12345/100000

(2) 0.(6)=6/9=2/3

(3) 0.1(6)=(16-1)/90=1/6

边上代码边讲:

#include<bits/stdc++.h>
using namespace std;
long long gcd(long long n,long long m)
{
	long long r;
	do
	{
		r=n%m;
		n=m;
		m=r;
	}while(m!=0);
	return n;
}//最大公因数,用来约分
int main()
{
	char s[5000];
	bool p=true;
	int t=0;
	scanf("%s",s);//字符串读入
	int l=0;
	long long integer=0;
	for(;s[l]!='.';l++)
		integer=integer*10+s[l]-48;//取出整数部分
	for(int i=0;i<strlen(s);i++) 
	if(s[i]=='(')//找到循环节
	{
		p=false;//是否为非循环小数
		t=i;//标记
		break;
	}
	if(s[l+1]=='(')//如果是纯循环小数
	{
		int len=strlen(s);
		long long a=0,b=0;
		l+=2;
		for(int i=l;i<len-1;i++) 
		{
			b=b*10+9;
			a=a*10+s[i]-48;
		}//公式计算
		a+=integer*b;
		cout<<a/gcd(a,b)<<"/"<<b/gcd(a,b);
	}
	else if(s[l+1]>='0'&&s[l+1]<='9'&&p)//如果是有限小数
	{
		int len=strlen(s);
		long long a=0,b=1;
		l++;
		for(int i=l;i<len;i++) 
		{
			b*=10;
			a=a*10+s[i]-48;
		}//公式计算
		a+=integer*b;
		cout<<a/gcd(a,b)<<"/"<<b/gcd(a,b);
	}
	else//如果是混循环小数
	{
		int len=strlen(s);
		long long a=0,b=0,c=0;
		l++;
		for(int i=l;i<len;i++) 
		if(s[i]>='0'&&s[i]<='9')
			a=a*10+s[i]-48;
		for(int i=l;i<t;i++)
		if(s[i]>='0'&&s[i]<='9')
			c=c*10+s[i]-48;
		for(int i=t+1;i<len-1;i++)
		b=b*10+9;
		for(int i=l;i<t;i++) b*=10;
		a=a-c;//公式计算(有点ma复杂)
		a+=integer*b;
		cout<<a/gcd(a,b)<<"/"<<b/gcd(a,b);
	}
	return 0;
}

各位886~

原文地址:https://www.cnblogs.com/oierscw/p/12548449.html