有关某数的因子——分数拆分

嗯,到了期末复习,额,期末预习的阶段了,白天忙着预习和还之前物理实验的债,晚上就给自己开点小灶、开开脑洞吧。

回到正题,既然说到某个数的因子,让我们先来看一道题吧。

对于一个整数n,我们求出1/n=1/a+1/b的所有a和b的正整数解的个数(但a=x,b=y和a=y,b=x看作同一组解)

解法1:首先让我们对1/n进行一系列的化简:

设正整数k,并且因为解不重复,不妨假设a>=b:

       1/n=1/(n+k)+k/n*(n+k)

            =1/(n+k)+k/(n^2+n*k)

            =1/(n+k)+1/(n^2/k+n)

            =1/(n+k)+1/(n+n^2/k)

即a=n+k,b=n+n^2/k。因为a>=b,所以k<=n^2/k,即k<=n。

又因为a,b均为正整数,那么n^2/k必为整数,即k为n^2的因子。

所以,满足条件的k的个数为n的因子数+1,也就是这道题解的个数。

解法2:

事实上,我们把n分解质因数之后,在n的所有约数中任取两个,就可以得到一组解。
例如:n=18,18的约数共有六个1,2,3,6,9,18。只要把分子分母都乘以这个分母的任意两个约数的和,就可以把一个分数拆分成两个分数的和。


可以看出,由于每次所选用的两个约数不同,所得的解也不相同。但是当选用的四个约数成比例时,他们的解就相同。如:选用1和2,3和6,9和18;或选用2和3,6和9时,解就相同。

所以,这种方法在实现时就需要我们在遍历枚举n的约数过程中,两个数的最大公约数必须为1才行。


———————————    华丽的分割线    ———————————————


嗯,如果上面的问题很容易明白的话,那么接下来让我们给问题增加点难度。

同样的,还是求分数拆分的问题,对于两个正整数n,m(m<n),对于m/n=1/a+1/b有多少组解呢?(a=x,b=y和a=y,b=x依旧看作同一组解)

我们这里继续延续上一题第二种解题方法的思想,这里的问题就是m不再为1了,该如何解决对约数枚举的取舍呢?

由上题的分母约数来看,对于m/n而言,上下同乘以某两个n的约数和,想得到两个分子为1的分数,就必须将m消除,因此,我们只需要对每组枚举再加一步if(约数和%m==0)的判断即可。


我想,当以上内容都了解之后,就可以尝试着完成一下HOJ 11537了,

题目链接:http://202.197.96.79:8080/online/?action=problem&type=show&id=11537&courseid=135

#include<cstdio>
using namespace std;
int m,n;
int a[10010];
int gcd(int a,int b){
    return b?gcd(b,a%b):a;
}
int main(){
    int cases=0;
    while(~scanf("%d%d",&m,&n)){
        int ans=0,temp=0,i,k;
        k=gcd(m,n),m/=k,n/=k;
        for(i=1;i*i<n;i++){
            if(n%i==0)
                a[temp++]=i,a[temp++]=n/i;
        }
        if(i*i==n) a[temp++]=i;
        if(m<=n)
            for(int i=0;i<temp;i++)
                for(int j=i;j<temp;j++)
                    if(gcd(a[i],a[j])==1)
                        if((a[i]+a[j])%m==0)
                            ans++;
        printf("Scenario #%d\n",++cases);
        if(ans>1) printf("Find %d solutions\n",ans);
        else if(ans==1) printf("Only one solution\n");
        else if(ans==0) printf("No solution\n");
    }
    return 0;
}
刚写完寻思试试去,表示OJ给了个SYSTEM FAULT。表示郁闷。。不过目测应该可以过,嗯




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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值