标签:10178 return Divisor min int big scanf HOJ small
最大公约数 |
Time Limit: 1000ms, Special Time Limit:2500ms, Memory Limit:32768KB |
Total submit users: 2211, Accepted users: 1898 |
Problem 10178 : No special judgement |
Problem description |
输入两个整数a,b(1≤a,b≤100000000),请编写程序求出他们的最大公约数。 |
Input |
第一个数n表示测试数据的个数,接下来的n行每行有两个整数a b,用空格隔开 |
Output |
输出n行,每行输出对应a,b的最大公约数 |
Sample Input |
|
Sample Output |
|
Problem Source |
CSU 1st Contest |
解法1:暴力,超时
算法:最容易想到的暴力法,从 a,b 两个数中的较小数开始向下逐步试探能否同时整除两个数,可以就得到答案,时间复杂度 O(max(a, b)) 结果超时。
#define _CRT_SECURE_NO_WARNINGS
#include <cstdio>
#include <vector>
int min(int a, int b) { return a < b ? a : b; }
int main()
{
int n, a, b, s, m;
scanf("%d", &n);
for (int i = 0; i < n; ++i)
{
scanf("%d %d", &a, &b);
s = 1, m = min(a, b);
for (int i = m; i >= 1; --i)
{
if (a % i == 0 && b % i == 0) {
s = i; break;
}
}
printf("%d\n", s);
}
return 0;
}
解法2:辗转相除法
#define _CRT_SECURE_NO_WARNINGS
#include <cstdio>
int max(int a, int b) { return a > b ? a : b; }
int min(int a, int b) { return a < b ? a : b; }
int main()
{
int n, a, b, big, small, f=0;
scanf("%d", &n);
for (int i = 0; i < n; ++i)
{
scanf("%d %d", &a, &b);
big = max(a, b);
small = min(a, b);
while (small)
{
f = small;
a == big ? a %= small : b %= small;
big = max(a, b);
small = min(a, b);
}
printf("%d\n", f);
}
return 0;
}
解法3:更相减损术
算法:可半者半之,不可半者,副置分母、子之数,以少减多,更相减损,求其等也。以等数约之。 —— 《九章算术》
该算法原本是为约分而设计的,就是用来给分子分母同时约分,约到最简分数,也可以用来求任意两个数的最大公约数。
翻译:
第一步:有两个数 a,b 现在要将其约到最简,如果 a, b 可以整除 2 就都约去 2,如果 a, b 均和 2 互质,执行第二步
第二步:分子分母两数做差,大的减掉小的,如果减完分子分母不相等,重复第二步,否则进入第三步
第三步:使用第二步中相减为零的两个被减数和减数,用其中一个对原来的分子分母进行约分,算法结束
图示:以题目数据 21 63 为例
AC:
#define _CRT_SECURE_NO_WARNINGS
#include <cstdio>
int max(int a, int b) { return a > b ? a : b; }
int min(int a, int b) { return a < b ? a : b; }
int main()
{
int n, a, b, big, small, f;
scanf("%d", &n);
for (int i = 0; i < n; ++i)
{
scanf("%d %d", &a, &b);
f = 1;
while (!(a & 1) && !(b & 1)) a >>= 1, b >>= 1, f <<= 1;
big = max(a, b);
small = min(a, b);
while (big != small)
{
a == big ? a -= b : b -= a;
big = max(a, b);
small = min(a, b);
}
printf("%d\n", small * f);
}
return 0;
}
标签:10178,return,Divisor,min,int,big,scanf,HOJ,small 来源: https://blog.csdn.net/chenhanxuan1999/article/details/111589909
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。