ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

[HOJ 10178] 最大公约数 (Greatest Common Divisor)

2020-12-23 19:02:51  阅读:237  来源: 互联网

标签: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
3
12 8
25 10
21 63
Sample Output
4
5
21
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. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有