基本要求:求N个数的最大公约数和最小公倍数。
提高题目:Hanks博士是BT(Bio-Tech,生物技术)领域的知名专家,他的儿子名叫Hankson。现在,刚刚放学回家的Hankson正在思考一个有趣的问题。
今天在课堂上,老师讲解了如何求两个正整数c1和c2的最大公约数和最小公倍数。现在Hankson认为自己已经熟练地掌握了这些知识,他开始思考一个“求公约数”和“求公倍数”之类问题的“逆问题”,这个问题是这样的:已知正整数a0,a1,b0,b1,设某未知正整数x满足:
1、 x和a0的最大公约数是a1;
2、 x和b0的最小公倍数是b1。
Hankson的“逆问题”就是求出满足条件的正整数x。但稍加思索之后,他发现这样的x并不唯一,甚至可能不存在。因此他转而开始考虑如何求解满足条件的x的个数。请你帮助他编程求解这个问题。
算法设计:
基本要求:1、使用穷举法求前两个数的最大公约数
2、通过递归的方式使剩余数以此和最大公约数进行运算,最终出N个数的最大公约数。
3、使用辗转相乘法的递归形式求前两个数的最小公倍数
4、通过递归的方式是剩余数与上一步求的最小公倍数以此辗转相乘,最终求出N个数的最小公倍数。
提高题:1、由最大公因数和最小公倍数的性质可知,令 p=a0/a1,q=b1/b0,它们与X的公因数为1,并且x也是b1(最小公倍数)的一个因子.
2、令x从1到sqrt(b1)中是b1(最小公倍数)的一个因子,除此外还有b1/x ,也可能是其中一个因子,用以上条件判断。
3、求最大公约数用了辗转相除法:
设两数为a,b设其中a 做被除数,b做除数,temp为余数
1、大数放a中、小数放b中;
2、求a/b的余数;
3、若temp=0则b为最大公约数;
4、如果temp!=0则把b的值给a、temp的值给a;
源代码:
基本要求:#include <stdio.h>
#define N 100 //数组长度
//输入个数和计算数
int input(int arg[])
{
int i,n;
printf(“请输入所计算值的数目(n>=2):”);
scanf("%d",&n);
if (n<2)//判断输入是否正确
{
printf("------输入错误----\n");
return input(arg);
}
printf(“输入运算数字:\n”);
for (i=0;i<n;i++)
{
scanf("%d",&arg[i]);
}
return n;
}
//穷举法求最大公约数
int gcd(int a,int b)
{
int i;
for (i=a;i>0;i–)
{
if(a%i0&&b%i 0)
return i;
}
}
//求n个数的最大公约数
int Gcd(int arg[],int n)
{
int i;
int c=arg[0];
for (i=1;i<n;i++)
{
c=gcd(c,arg[i]);
}
return c;
}
//最大公倍数
int lcm(int x,int y)
{
return x*y/gcd(x,y);
}
//n个数求最大公倍数
int Lcm(int arg[],int n)
{
int i;
int s=1;
for (i=0;i<n;i++)
{
s=lcm(s,arg[i]);
}
return s;
}
int main()
{
int arg[N];
int n;
int i=1;
n=input(arg);
printf(“最大公约数为 %d\n”,Gcd(arg,n));
printf(“最小公倍数为 %d\n”,Lcm(arg,n));
return 0;
}
提高题:
#include<stdio.h>
//求最大公因数
int gcd(int a,int b)
{
if(b==0)
return a;
else return gcd(b,a%b);;
}
int main()
{
int t,a[20],i=0,num;
scanf("%d",&t);
num=t;
while(t)
{
int a0,a1,b0,b1;
scanf("%d%d%d%d",&a0,&a1,&b0,&b1);
int p=a0/a1,q=b1/b0,count=0;//p为a0和a1的除数,q为b1和b0的除数,count为计数器
for(int x=1;x*x<=b1;x++)
if(b1%x0)
{
if(x%a10&&gcd(x/a1,p)1&&gcd(q,b1/x)1) count++;
int y=b1/x;
if(xy) continue;
if(y%a10&&gcd(y/a1,p)==1&&gcd(q,b1/y)==1) count++;
}
a[i]=count;
i++;
t–;
}
for(i=0;i<num;i++)
{
printf("%d\n",a[i]);
}
return 0;
}
总结:本次作业我发现了自己的很多问题,例如写代码命名不规范,没有习惯写注释,最后自己都搞不通写了什么。写程序不会分模块化,一骨碌写完,最后一堆错误。在慢慢改错的过程中,我逐渐适应了有错误通过调试和测试部分代码来解决。写提高题的时候思考了很久都没有思路,觉得无从下手,最后上网查了相关资料终于理明白了整道题。这说明我在算法题上欠缺还是很大,我要在这一方面更下功夫,更努力。