题解:P1072 [NOIP2009 提高组] Hankson 的趣味题

· · 题解

考虑根号算法。

先思考暴力的思路,就是枚举,对每一个满足条件的数都做一次统计,可以骗到 50 分。

#include <bits/stdc++.h>
using namespace std;
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        int a,b,c,d;
        scanf("%d%d%d%d",&a,&b,&c,&d);
        int cnt=0;
        for(int i=1;i<=d;i++)
        {
            if(d%i==0)
            {
                if(__gcd(i,a)==b&&i/__gcd(i,c)*c==d) cnt++;
            }

        }
        printf("%d\n",cnt);
    }
}

发现上面的代码执行的次数连整数类型都存不下,所以我们猜测需要根号时间复杂度等。

我们发现很多枚举次数都是不需要的,联想到判断质数时只需枚举到根号,因为除了平方根外,剩下的因数都成对分布在一左一右。

那我们只需枚举到根号,大于根号的因数都用小因数除出来。

#include <bits/stdc++.h>
using namespace std;
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        int a,b,c,d;
        scanf("%d%d%d%d",&a,&b,&c,&d);
        int cnt=0;
        for(int i=1;i<=sqrt(d);i++)
        {
            if(d%i==0)
            {
                if(__gcd(i,a)==b&&i/__gcd(i,c)*c==d) cnt++;
                int x=d/i;
                if(x!=i&&__gcd(x,a)==b&&x/__gcd(x,c)*c==d) cnt++;
            }

        }
        printf("%d\n",cnt);
    }
}