[NOIP2009] $Hankson$ 的趣味题 (数论,gcd)

题目链接

Solution

此题,用到的结论都是比较浅显的,但是,我竟然没想到反过来枚举...
只有50分... 被自己蠢哭...

结论比较浅显:

1.对于两个正整数\(a\),\(b\),设 \(gcd(a,b)=k\),则存在\(gcd(a/k,b/k)=1\).

也就是说 \(x=k_1*a_1\),\(a_0=k_2*a_1\),它们最大公约数为\(a_1\),那么要求 \(k_1\)\(k_2\) 必须互质,否则它们的最大公约数会是 \(gcd(k_1,k_2)*a_1\).

2.对于两个正整数\(a\),\(b\),设\(lcm(a,b)=k\),则存在\(gcd(k/a,k/b)=1\).

比较浅显,可以由 \(a*b=gcd(a,b)*lcm(a,b)\) 推出来.

然后通过分析题意结论,便可以分析出 \(x\) 满足 \(x\)\(b_1\) 的因子,并且满足是 \(a_1\) 的倍数.
所以我们直接 \(\sqrt{b_1}\) 枚举其因子,并且判断是否满足上述条件即可.

Code

100 分做法

#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll n,a1,a0,b0,b1;

ll gcd(ll x,ll y)
{
    if(y==0)return x;
    else return gcd(y,x%y);
}

int main()
{
    scanf("%lld",&n);
    while(n--)
    {
        scanf("%lld%lld%lld%lld",&a0,&a1,&b0,&b1);
        if(b1%a1!=0){printf("0\n");continue;}
        ll ans=0,maxx=sqrt(b1);
        for(int x=1;x<=maxx;x++)
        {
            if(b1%x!=0)continue;
            if(x%a1==0)
            if(gcd(b1/b0,b1/x)==1)
            if(gcd(x/a1,a0/a1)==1)
            ans++;
            if(b1/x==x)continue;
            ll y=b1/x;
            if(y%a1==0)
            if(gcd(b1/b0,b1/y)==1)
            if(gcd(y/a1,a0/a1)==1)
            ans++;
        }
        printf("%lld\n",ans);
    }
}

50 分做法(暴力枚举 \(a_1\) 的倍数,然后判断)

#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll n,a1,a0,b0,b1;

ll gcd(ll x,ll y)
{
    if(y==0)return x;
    else return gcd(y,x%y);
}

int main()
{
    scanf("%lld",&n);
    while(n--)
    {
        scanf("%lld%lld%lld%lld",&a0,&a1,&b0,&b1);
        if(b1%a1!=0){printf("0\n");continue;}
        ll tt=0,ans=0;
        while(1)
        {
            tt++;
            if(tt*a1>b1)break;
            ll x=tt*a1;
            if(b1%x!=0)continue;
            if(gcd(x,a0)!=a1)continue;
            if(x*b0!=gcd(b0,x)*b1)continue;
            ans++;
        }
        printf("%lld\n",ans);
    }
}

转载于:https://www.cnblogs.com/Kv-Stalin/p/9526426.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值