算法竞赛入门经典第十章学习笔记 除法表达式 最大公约数

除法表达式
题目:给出除法表达式: X 1 / X 2 / X 3 / . . . / X k X_1/X_2/X_3/.../X_k X1/X2/X3/.../Xk,其中 X i X_i Xi是整数。除法表达式应当按照从左到右的顺序求和,例如表达式 1 / 2 / 1 / 2 1/2/1/2 1/2/1/2的值为 1 / 4 1/4 1/4。但可以在表达式中嵌入括号以改变计算顺序,例如表达式 ( 1 / 2 ) / ( 1 / 2 ) (1/2)/(1/2) (1/2)/(1/2)的值为1。

分析:加括号以后一定是一些项在分母上一些项在分子上。如果想要容易整除,分母上的项要尽量少。可以发现,无论怎么加括号,第二项 X 2 X_2 X2一定要放在分母上。其它项呢?发现如果用如下加括号的方式:

E = X 1 / ( X 2 / X 3 / . . . / X k ) = X 1 / X 3 / X 4 / . . . / X k X 2 E=X_1/(X_2/X_3/.../X_k)=\frac{X_1/X_3/X_4/.../X_k}{X_2}\quad E=X1/(X2/X3/.../Xk)=X2X1/X3/X4/.../Xk

只需要判断E是否为整数。直接计算结果很大可能溢出。对于这种大整数的计算可以用高精度运算,但是需要进行k-2次乘法和1次除法,比较麻烦。也可以使用唯一分解定理,暂时不讨论。第三种方法是通过找最大公约数进行约分:对于每个 X i X_i Xi,找到 X i 和 X 2 X_i和X_2 XiX2的最大公约数,然后约掉。 X 2 X_2 X2会逐渐变小,如果 X 2 X_2 X2的所有因子都能约掉,即 X 2 = 1 X_2=1 X2=1那么可以整除。如果一直到最后 X 2 X_2 X2还是有约不掉的因子,那么不能整除。寻找最大公约数有一个快速简便的方法,称为欧几里德法或辗转相除法,要能够熟练使用。

#include<iostream>
#include<vector>
using namespace std;

int gcd(int a, int b)
{
  return b == 0 ? a : gcd(b, a%b);
}

bool judge(vector<int> v)
{
 if(v.size()==1) return true;
 if(!v.size() || !v[1]) return false;
 int x2 = v[1];
 x2 /= gcd(x2, v[0]);
 for(int i = 2; i < v.size(); i++)
 {
   x2 /= gcd(x2, v[i]);
   if(x2 == 1) return true;
 }
if(x2 == 1) return true;
return false;
}

int main()
{
  vector<int> X;
  int x;
  cout<<"Enter numbers, 'q' to finish: "<<endl;
  while(cin>>x)
    X.push_back(x);
  cout<<"Answer is: "<<(judge(X)?"True":"False");
  return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值