数论初步-除法表达式(辗转相除法)

给出这样一个除法表达式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

 

 

posted @ 2012-12-26 18:13  tsubasa_wp  阅读(479)  评论(0编辑  收藏  举报