20求助

P1029 [NOIP2001 普及组] 最大公约数和最小公倍数问题

seele_waiting @ 2023-05-27 18:21:27

#include<bits/stdc++.h>
using namespace std;
int s(int a,int b){
    for(int i=min(a,b);i*i>=0;i--){
        if(a%i==0&&b%i==0){
            return i;
        }
    }
    return 0;
}
int main(){
    int n,m,cnt=0;
    cin>>n>>m;
    for(int i=n;i*i<=m;i++){
        for(int j=(n+m)/2;j<=m;j++){
            if(i*j==m&&s(i,j)==n){
                cnt++;
            }
        }
    }
    cout<<cnt;
    return 0;
}

by 2011Andy @ 2023-05-27 18:58:21

请学习使用__gcd()


by bingxin @ 2023-05-27 21:10:33

首先你的gcd除了没有用欧几里得优化算法,正确性是没有问题的
然而在主函数里,符合题目要求的 P,Q 数对的乘积明显应为 n \times m (这是gcd/lcm的性质应该不需要展开说吧...)在判定时是有问题的
最后, P,Q 两数(在数轴上)和 n,m 的中点没有任何关系...写代码之前一定要仔细思考为什么这么做


by bingxin @ 2023-05-27 21:16:56

这里浅浅贴一下我代码枚举的那部分,希望能帮到你

for (int i = n, up = sqrt(mul); i <= up; i++) // mul为n, m乘积,同时避免多次计算和溢出
{
    if (mul % i)
        continue;
    if (gcd(i, mul / i) == x)
        cnt += i == mul / i ? 1 : 2; 
    /* 举个例子:乘积同为36,(3,12)和(12,3)能产生两个数对,但(6,6)只算一个数对,所以特判一下平方数 */
}

|