中南月赛试题Decimal
Description
任意一个分数都是有理数,对于任意一个有限小数,我们都可以表示成一个无限循环小数的形式(在其末尾添加0),对于任意一个无限循环小数都可以转化成一个分数。现在你的任务就是将任意一个无限循环小数转化成既约分数形式。所谓既约分数表示,分子和分母的最大公约数是1。
Input
有多组数据。
每组数据一行。输入为0.a1a2a3...ak(b1b2...bm)的形式,其中a1a2a3...ak为非循环部分,(b1b2b3..bm)为循环部分。数据保证非循环部分的长度k和循环部分的长度m不会超过8.
Output
对于每组测试数据输出A/B,其中A是分子,B是分母,A,B均为整数。
Sample Input
0.0(714285) 0.0(5) 0.9(671)
Sample Output
1/14 1/18 4831/4995
题意:将有理数化为分数形式
题解:将该有理数拆分为两个数的和的形式。前面有限为和后面的循环位
#include<stdio.h>
#include<iostream>
#include<string>
#include<math.h>
#define ll long long
using namespace std;
ll pow(ll n)
{
ll s=1;
while(n--) s*=10;
return s;
}
ll gcd(ll a,ll b)
{
if(b==0) return a;
else return gcd(b,a%b);
}
int main()
{
//freopen("a.txt","r",stdin);
string s;
ll i,len1,len2,pos,s1,s2,flag;
while(cin>>s)
{
flag=0;
s1=0;
s2=0;
for(i=0;i<s.length();i++)
{
if(s[i]=='(') {pos=i;flag=1;}
}
if(flag==0)
{
len1=s.length()-2;
for(i=2;i<=s.length()-1;i++) s1=s1*10+s[i]-'0';
int c=gcd(s1,(int)pow(len1));
printf("%lld/%lld\n",s1/c,(ll)pow(len1)/c);
}
else
{
len1=pos-2;
len2=s.length()-2-pos;
for(i=2;i<=pos-1;i++)
{
s1=s1*10+s[i]-'0';
}
for(i=pos+1;i<s.length()-1;i++)
{
s2=s2*10+s[i]-'0';
}
ll temp1=s1*(pow(len2)-1)+s2;
ll temp2=pow(len1)*(pow(len2)-1);
ll c;
if(len2==0)
{
c=gcd(s1,(ll)pow(len1));
printf("%lld/%lld\n",s1/c,(ll)pow(len1)/c);
}
else
{
ll c=gcd(temp1,temp2);
printf("%lld/%lld\n",temp1/c,temp2/c);
}
}
}
return 0;
}