Hoj 2305 Diophantus of Alexandria

本文介绍了解决一个特定数学问题的两种算法:一种是通过枚举法直接求解,另一种是利用数论中的因子分解技巧进行优化。文章提供了完整的C++代码实现,并对比了两种方法的效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目链接:http://acm.hit.edu.cn/hoj/problem/view?id=2305

题意:给定的数n,求1/x + 1/y = 1/n 有多少种情况,x<=y,都是正整数。

我们很容易求得:n<x<=2*n.

第一种思路是枚举遍历x,判断y是不是正整数就行了,注意判断的手段,用floor(y+0.5)?= y来判断。但是很不幸会超时。

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;

int solve(int n)
{
    int ans = 0;
    for(int x=n+1;x<=2*n;x++)
    {
        double y = ((double)n*x)/(x-n);
        if(floor(y + 0.5) == y) ans++;
    }
    return ans;
}

int main()
{
#ifndef ONLINE_JUDGE
    freopen("in.txt","r",stdin);
#endif
    int t;
    scanf(" %d",&t);
    int cas = 0;
    int n;
    while(t--)
    {
        cas++;
        scanf(" %d",&n);
        printf("Scenario #%d:\n",cas);
        printf("%d\n",solve(n));
        printf("\n");
    }
    return 0;
}

第二种方法就是因子分解,我们可以整理成(x-n)*(y-n) = n^2

那么,我们求n^2的因子个数就行了。我们只要会求n的因子个数就行了。我们可以采取任何一个数都可以分解成多个素数的幂的乘机这种方式。枚举时可以枚举sqrt(n)以内的素因子,因为剩下的大于sqrt(n)的因子肯定是一个素数。它自己的因子数是2.平方以后就是3了。

见代码:

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;

int solve(int n)
{
    int ans = 1;
    for(int i=2;i<=sqrt(n);i++)
    {
        if(n%i == 0)
        {
            int t = 0;
            while(n%i == 0)
            {
                t++;
                n = n/i;
            }
            ans *= (t*2+1);
        }
    }
    if(n!=1) ans*=3;
    ans = (ans + 1)/2;
    return ans;
}

int main()
{
#ifndef ONLINE_JUDGE
    freopen("in.txt","r",stdin);
#endif
    int t;
    scanf(" %d",&t);
    int cas = 0;
    int n;
    while(t--)
    {
        cas++;
        scanf(" %d",&n);
        printf("Scenario #%d:\n",cas);
        printf("%d\n",solve(n));
        printf("\n");
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值