数论初步-除法表达式(辗转相除法)
给出这样一个除法表达式X1/X2/X3../Xn: 输入X1 X2 X3 X4…Xn, 判断是否可以通过添加括号使表达式的值为整数.
解析:
X1/X2/X3../Xn = X1 / (X2*X3*X4..Xn)
可以推出(X2一定在分母位置):
X1/X2/X3../Xn = X1 / ( X2 / X3 / X4.../Xn ) = ( X1*X3 *X4..Xn ) / X2
问题就变成了求 ( X1*X3 *X4..Xn ) 能不能被X2整除.
方法1: 高精度运算.
方法2: 利用唯一分解定理, 把X2分解成若干素数相乘形式, 然后依次判断每个素数是否是( X1*X3 *X4..Xn )的约数(比较这个素数的指数和).
方法3: 直接约分.每次越掉X2和Xi的最大公约数gcd(Xi, X2). 当且仅当约分结束后X2=1时, 表达式能够被整除.
int judge(int *x) { X[2] /= gcd(X[2], X[1]); for ( int i = 3; i <= k; i++ ) { X[2] /= gcd(X[2], X[i]); } return X[2] == 1; } int gcd(int a, int b) { return b == 0 ? a : gcd(b, a%b); }
算法的时间效率取决于gcd算法.
这里使用了著名的数论算法:辗转相除法(欧几里德算法).
详细资料戳wiki:
http://zh.wikipedia.org/wiki/%E8%BC%BE%E8%BD%89%E7%9B%B8%E9%99%A4%E6%B3%95