HDOJ-5019-Revenge of GCD 解题报告

来源:互联网 发布:visio画数据流程图 编辑:程序博客网 时间:2024/05/18 02:17

       求k大GCD。题意:给三个正整数x,y和k,求x和y的第k大公约数。


       我的解题思路:首先根据求最大公约数的原理,k大公约数是最大公约数的因子。那么求k大公约数就转换成为了求最大公约数的第k大因子。可以通过唯一分解定理得到最大公约数的因子个数,然后根据情况判断是否枚举。


       我的解题代码:

#include <cstdio>#include <cstdlib>#include <cstring>#include <cctype>#include <cmath>#include <algorithm>using namespace std;typedef long long Long;Long x, y, k;Long Gcd(Long a, Long b);Long Factor(Long x);        //返回因子个数int main(){    int t;    scanf("%d", &t);    while (t--)    {        scanf("%lld %lld %lld", &x, &y, &k);        Long gcd = Gcd(x, y);        Long fn = Factor(gcd);        if (fn < k) puts("-1");        else if (k == fn) puts("1");        else if (k == 1) printf("%lld\n", gcd);        else if (fn % 2 == 1 && (fn - 1) / 2 == k) printf("%lld\n", (Long)sqrt(gcd + 0.5));        else        {            Long cnt = (Long)sqrt(gcd + 0.5) + 1;            Long times = 0;            for (Long i=1; i<cnt; ++i)            {                if (gcd % i == 0)                {                    times++;                    if (k == times || k == fn - times + 1)                    {                        printf("%lld\n", k == times ? gcd / i : i);                        break;                    }                }            }        }    }    return 0;}Long Gcd(Long a, Long b){    return b == 0 ? a : Gcd(b, a % b);}Long Factor(Long x){    Long cnt = (Long)sqrt(x + 0.5) + 1;    Long ans = 1;    for (Long i=2; i<cnt; ++i)    {        if (x % i == 0)        {            Long temp = 0;            while (x % i == 0)            {                x /= i;                temp++;            }            ans *= 1 + temp;        }    }    if (x > 1) ans *= 2;    return ans;}


0 0
原创粉丝点击