【题目】
题目描述:已知两个正整数a和b,求这两个数的最大公约数GCD(a,b)。
输入格式:测试数据包括多组数据。测试数据的第一行是一个整数n(n<50),表示有n组输入数据。其后有n行数据,每行数据包括由空格分隔的两个正整数a和b。
输出格式:对于每组测试数据,输出一行,给出对应输入数据的GCD(a,b)。
输入样例:
1
24 16
输出样例:
8
一.穷举法:
1.抓最大公约数的特点:
(1)最大:较小者逐次减1
(2)公约:可整除两者
2.缺点:
(1)暴力
(2)数大效率低下
二.欧几里得算法(高代曾学:辗转相除法)
1.回顾:
f=g*q1+r1
g=r1*q2+r2
r1=r2*q3+r3
......求到r(n)==0为止
归纳:f与g的最大公约数是最后一个不为0的余数。
2.
#include<stdio.h>
int GCD(int a,int b)
{
int r;//由于r无初值,可先执行后判断,用do while
do
{
r=a%b;
a=b;
b=r;
}while(r!=0);
return a;
}
/*1.a>b,a<=b经分析,代码可同
2.a=b*q1+r1
b=r1*q2+r2
q不需要,看余数
*/
int main()
{
int n;
scanf("%d",&n);
while(n--)//每次处理两个数,不需用数组,循环控制n行输入
{
int a,b;
scanf("%d%d",&a,&b);
printf("%d\n",GCD(a,b));
}
return 0;
}
三.递归
1.数学性质:
(1)a和b的最大公约数与b-a(b>a),a-b(a>b)的同--->递减至相等(我现在对递归的理解是递归是在函数中对函数的再次调用,可用于代替循环)
(2)a==b,为a或b
2.
(1)非递归算法(循环)
#include<stdio.h>
int GCD(int a,int b)
{
while(a!=b)
{
if(a>b)
a=a-b;
else
b=b-a;//让大的一方变小
}
return a;
}
(2)递归代码
#include<stdio.h>
int GCD(int a,int b)
{
if(a>b)
return GCD(a-b,b);
else if(a==b){
return a;
}
else return GCD(a,b-a);
}//取小者
【注】学艺不精,还望各位大师批评指正。