问题描述–连分数
定义一个高为n的连分数如下:
给出两个数,一个用p/q的方式表达,另一个用高度为n的连分数表示,判断是否相等。
输入
输入可以包含多组,每组包含两部分用来表示两种形式的分数,第一部份是p和q(1<=q<=p<= 1018
,表示分数p/q;然后是一个数字n(1<=n<=90)和由n个数 a(1<=a<=1018)代表的连分数
输出
如果相等则输出YES,否则输出NO
思考
对于这道题,最初我想到的是,分别将两个分数计算一下,换算为小数,后来发现不对,因为在计算机中由于位数的限制,存在精度上的误差,不能完全按照数学上的相等来比较,对于两个都非常小的数,即使不等,计算机也可能判断相等,例如如果知道一定的误差范围,那么可以根据两个数相减,差值小于规定误差或大于规定误差判断,但是在本题中显然无法获取误差的范围。一个很直接的方法就是保持分数形式,将连分数转化为分数形式,且都是最简分数,然后比较是否相等。
#include<stdio.h>
unsigned long long int gcd(unsigned long long int a,unsigned long long int b);
int main()
{
int n,i;
unsigned long long int p,q,c,t,x,y;
while(scanf("%llu %llu %d",&p,&q,&n)!=EOF)
{
unsigned long long int a[n];//将连分数的各个项存入数组中,迭代计算
for(i=0;i<n;i++)
scanf("%llu",&a[i]);
c=gcd(p,q);
p=p/c;
q=q/c;
x=a[n-1];
y=1;
t=1;
for(i=n-2;i>=0;i--)
{//连分数的迭代计算,计算过程同手算过程
x=a[i]*a[i+1]+t;
y=a[i+1];
if(i!=0)
{
a[i]=x;
t=y;
}
}
c=gcd(x,y);
x=x/c;
y=y/c;
if(x==p&&y==q)
printf("YES");
else
printf("NO");
printf("\n");
}
return 0;
}
//gcd函数是为了得到分子和分母最大公因数,然后化简
unsigned long long int gcd(unsigned long long int a,unsigned long long int b)
{
unsigned long long int c;
while(b!=0)
{
c=a%b;
a=b;
b=c;
}
return a;
}