给你两个个小数,你能计算出它们的和是多少吗?
你肯定会说,so easy。
可是,如果这些小数中有的是无限循环小数呢?
无限循环小数一般有三部分,整数部分,小数不循环部分,和小数循环部分。
比如:
1.2(34)的三部分分别为1 2 34.
2.(04)的整数部分为2,小数不循环部分不存在,小数循环部分为04
2.4的整数部分为2,小数不循环部分为4,小数循环部分不存在
一般小数循环部分在小数的最后。
现在,请计算两个无限循环小数的和
-
输入
-
第一行输入一个整数N,表示有N行测试数据(1<=N<=100)
第二行输入六个字符串S1,T1,R1,S2,T2,R2,分别别示第一个和第二个循环小数的整数部分,小数不循环部分与小数部分。(如果该部分不存在,则输入$)
整数部分,小数不循环部分,循环部分长度皆不超过10位。
输入的各部分皆为正数。
输出
- 输出两个数的和,输出结果请转换成最简分数(不要写成带分数的形式)。(如果是整数则直接输出) 样例输入
-
3 1 $ 3 2 $ 3 0 1 3 0 $ 6 2 03 $ 2 4 $
样例输出
-
11/3 4/5 443/100
拿到这样一个问题,我们往往会从最简单的情况入手,因为所有的小数都可以分解成一个整数和一个纯小数之和,不妨只考虑大于 0,小于 1 的纯小数,且暂时不考虑分子和分母的约分,先设法将其表示为分数形式,然后再进行约分。题目中输入的小数,要么为有限小数X=0.a1 a2 …an ,要么为无限循环小数
X=0.a1 a2 …an (b1 b2 …bm),X 表示式中的字母a1 a2 …an,b1 b2 …bm 都是 0~9 的数字,括号部分(b1b2 …bm)表示循环节,我们需要处理的就是以上两种情况。
对于有限小数X=0.a1a2…an 来说,这个问题比较简单,X 就等于(a1a2 …an )/10^n。
对于无限循环小数X=0.a1 a2 …an (b1 b2 …bm )来说,其复杂部分在于小数点后同时有非循环部分和循环部分,我们可以做如下的转换:
X = 0. a1a2 …an (b1b2 …bm) ⇒
10^n* X= a1a2 …an.(b1 b2…bm) ⇒
10^n* X= a1a2 …an+0.(b1 b2 …bm) ⇒
X = (a1a2 …an+0.(b1b2…bm))/10^n
对于整数部分a1 a2 …an,不需要做额外处理,只需要把小数部分转化为分数形式再加上这个整数即可。对于后面的无限循环部分,可以采用如下方式进行处理:
令Y=0. b1b2…bm,那么
10^m*Y= b1b2 …bm.(b1b2 …bm) ⇒
10^m*Y= b1 b2 …bm+0.(b1 b2 …bm) ⇒
10^m*Y-Y= b1b2 …bm ⇒
Y= b1b2 …bm /(10^m-1) 将Y 代入前面的X 的等式可得:
X = (a1 a2 …an + Y)/10^n = (a1a2 …an+ b1b2 …bm/(10^m-1))/10^n
= ((a1 a2…an )*(10^m-1)+ (b1 b2 …bm))/ ((10^m-1)*10^n)
至此,便可以得到任意一个有限小数或无限循环小数的分数表示,但是此时分母未必是最简的,接下来的任务就是让分母最小,即对分子和分母进行约分
例如,对于小数0.3(33),根据上述方法,可以转化为分数:
0.3(33) =
(3 *(10^2-1)+ 33 )/ ((10^2-1)*10)
= (3*99+33 )/990
= 1 / 3
对于小数0. 285714(285714),我们也可以算出:
0. 285714(285714)
= (285714 * (10^6-1) + 285714) / ((10^6-1)*10^6)
= (285714*999999 +285714) / 999999000000
= 285714 / 999999
= 2/7
ac代码:
#include <iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;
long long turn(long long x,long long y)
{
while(y!=0)
{
int r=x%y;
x=y;
y=r;
}
return x;
}
long long ten(int x)
{
long long sum=1;
while(x)
{
sum*=10;
x--;
}
return sum;
}
int main()
{
int n,x,y;
long long a,b,c,a1,b1,c1,w;
long long u,d,u1,d1;
char char1[21],char2[21],char3[21],char4[21],char5[21],char6[21];
scanf("%d",&n);
while(n--)
{
scanf("%s %s %s %s %s %s",char1,char2,char3,char4,char5,char6);
x=strlen(char2);
y=strlen(char3);
if(char2[0]=='$'&&char3[0]!='$')
{
c=atoll(char3);
//字符串取long long 型,字符串取long型为atol,字符串取浮点型atof,字符串取整型atoi
u=c;
d=(ten(y)-1);
w=turn(u,d);
u/=w;d/=w;
}
else if(char2[0]!='$'&&char3[0]!='$')
{
b=atoll(char2); c=atoll(char3);
u=(b*(ten(y)-1)+c);
d=ten(x)*(ten(y)-1);
w=turn(u,d);
u/=w;d/=w;
}
else if(char2[0]!='$'&&char3[0]=='$')
{
u=atoll(char2);
d=ten(x);
}
else
{
u=0;d=1;
}
x=strlen(char5);
y=strlen(char6);
if(char5[0]=='$'&&char6[0]!='$')
{
c1=atoll(char6);u1=c1;
d1=(ten(y)-1);
w=turn(u1,d1);
u1/=w;d1/=w;
}
else if(char5[0]!='$'&&char6[0]!='$')
{
b1=atoll(char5);c1=atoll(char6);
u1=(b1*(ten(y)-1)+c1);
d1=ten(x)*(ten(y)-1);
w=turn(u1,d1);
u1/=w;d1/=w;
}
else if(char5[0]!='$'&&char6[0]=='$')
{
u1=atoll(char5);
d1=ten(x);
}
else
{
u1=0;d1=1;
}
if(char1[0]=='$') a=0;
else a=atoll(char1);
if(char4[0]=='$') a1=0;
else a1=atoll(char4);
u=u*d1+u1*d;
d*=d1;
w=turn(u,d);
u/=w;d/=w;
u=(a+a1)*d+u;
w=turn(u,d);
u/=w;d/=w;
if(d!=1)
printf("%lld/%lld\n",u,d);
else
printf("%lld\n",u);
}
return 0;
}
最后计算可以简化:
#include <iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;
long long turn(long long x,long long y)
{
while(y!=0)
{
int r=x%y;
x=y;
y=r;
}
return x;
}
long long ten(int x)
{
long long sum=1;
while(x)
{
sum*=10;
x--;
}
return sum;
}
int main()
{
int n,x,y;
long long a,b,c,a1,b1,c1,w;
long long u,d,u1,d1;
char char1[21],char2[21],char3[21],char4[21],char5[21],char6[21];
scanf("%d",&n);
while(n--)
{
scanf("%s %s %s %s %s %s",char1,char2,char3,char4,char5,char6);
x=strlen(char2);
y=strlen(char3);
if(char2[0]=='$'&&char3[0]!='$')
{
c=atoll(char3);
u=c;
d=(ten(y)-1);
w=turn(u,d);
u/=w;d/=w;
}
else if(char2[0]!='$'&&char3[0]!='$')
{
b=atoll(char2); c=atoll(char3);
u=(b*(ten(y)-1)+c);
d=ten(x)*(ten(y)-1);
w=turn(u,d);
u/=w;d/=w;
}
else if(char2[0]!='$'&&char3[0]=='$')
{
u=atoll(char2);
d=ten(x);
}
else
{
u=0;d=1;
}
x=strlen(char5);
y=strlen(char6);
if(char5[0]=='$'&&char6[0]!='$')
{
c1=atoll(char6);u1=c1;
d1=(ten(y)-1);
w=turn(u1,d1);
u1/=w;d1/=w;
}
else if(char5[0]!='$'&&char6[0]!='$')
{
b1=atoll(char5);c1=atoll(char6);
u1=(b1*(ten(y)-1)+c1);
d1=ten(x)*(ten(y)-1);
w=turn(u1,d1);
u1/=w;d1/=w;
}
else if(char5[0]!='$'&&char6[0]=='$')
{
u1=atoll(char5);
d1=ten(x);
}
else
{
u1=0;d1=1;
}
if(char1[0]=='$') a=0;
else a=atoll(char1);
if(char4[0]=='$') a1=0;
else a1=atoll(char4);
u=u*d1+u1*d;
d*=d1;
u=(a+a1)*d+u;
w=turn(u,d);
u/=w;d/=w;
if(d!=1)
printf("%lld/%lld\n",u,d);
else
printf("%lld\n",u);
}
return 0;
}