算法竞赛入门经典:第十章 数学概念与方法 10.1除法表达式

来源:互联网 发布:linux acl mask 编辑:程序博客网 时间:2024/05/22 13:42
/*数论初步:除法表达式:给出这样的除法表达式:X1/X2/X3/.../Xk,其中Xi是正整数。除法表达式应当从左到右的顺序求和,例如表达式1/2/1/2的值为1/4。但可以在表达式中嵌入括号可以改变计算顺序,例如表达式(1/2)/(1/2)的值为1。输入X1,X2,..,Xk,判断是否可以通过添加括号,使表达式的值为整数。K<=10000,Xi<=10^9.分析:表达式的值一定可以写成A/B的形式:A是其中一些Xi的乘积,而B是其他数的成绩。X2必须放在分母位置,其他数可以放在分子位置:E=X1/(X2/X3/..Xk)=X1X3X4...Xk/X2接下来判断E是否为整数。采用直接约分方法:每次约掉Xi和X2的最大公约数gcd(Xi,X2),当且仅当约分结束后X2=1时E为整数最大公约数采用辗转相除法输入:41 2 1 231 2 3输出:10*//*关键:1 表达式的值一定可以写成A/B的形式:A是其中一些Xi的乘积,而B是其他数的成绩。X2必须放在分母位置,其他数可以放在分子位置:E=X1/(X2/X3/..Xk)=X1X3X4...Xk/X22 采用直接约分方法:每次约掉Xi和X2的最大公约数gcd(Xi,X2),当且仅当约分结束后X2=1时E为整数X[2] /= gcd(X[1],X[2]);for(int i = 3 ; i <= k ; i++){X[2] /= gcd(X[i],X[2]);}return X[2] == 1;3 最大公约数采用辗转相除法 :gcd(a,b) = gcd(b,a%b),也叫欧几里德算法4 唯一分解定理:把X2写成素数相乘的形式a = p1^e1*p2^e2*...pr^erb = p1^f1*p2*f2*...pr^frgcd(a,b) = p1^min(e1,f1)*p2^min(e2,f2)*...pr^min(er,fr)lcm(a,b) = p2^max(e1,f1)*p2^max(e2,f2)*...pr^max(er,fr)gcd(a,b)*lcm(a,b) = a*blcm(a,b) = a/gcd(a,b)*b.注意不要写成ab/gcd(a,b),因为a*b可能越界a = 6,b = 8a = 2^1*3^1b = 2^3*3^0gcd(6,8) = 2^1*3^0 = 2lcm(6,8) = 2^3*3^1 = 24*/#include <stdio.h>#define MAXSIZE 1024int gcd(int a,int b)//这里不需要判断a和b的大小{return b == 0 ? a : gcd(b,a%b);}int judge(int* X,int k){X[2] /= gcd(X[1],X[2]);for(int i = 3 ; i <= k ; i++){X[2] /= gcd(X[i],X[2]);}return (X[2] == 1);}void process(){int k;while(EOF != scanf("%d",&k)){int iArr[MAXSIZE];for(int i = 1 ; i <= k ; i++){scanf("%d",&iArr[i]);}printf("%d\n",judge(iArr,k));}}int main(int argc,char* argv[]){process();getchar();return 0;}

0 0