整数拆分问题(1)

原创 2017年01月02日 21:48:23


我们一起来看看这个问题,说实话,当时一看到这题的时候我怕了,不过想通后那叫一个爽啊!得意

题意:给你一个N,求满足1/X+1/Y=1/N的X,Y种类数


当你看到这题的时候,你会怎么做呢?

当时我看到第一反应就是先化简,因为1/X这个数肯定是比1小的小数,这个精度问题是个大问题,而且两个小数相加也不会完全等于那个小数。所以,想办法划成整数关系式。

两边同乘XY,得  Y+X=XY/N

转换,得        N=XY/(X+Y)

然后直接求吗?不不不,N是个整数,难道你就能保证右边除出来是整数吗?!

然后,绞尽脑汁,沉思,深呼吸,学下一休哥,忽然想到了!

你可以保证,当两个分数相加要等于一个分数时,两个分数的分母肯定都大于这个分数的分母,也就是X,Y>N

我们可以假设,X=N+u,Y=N+v, 其中u,v肯定都是大于0的整数

然后代入,简化出来,不可思议,N^2=uv

而一个整数N都是可以拆成 N=p1^a1 * p2^a2 *……*pn^an 的形式

此时N拆成两个数相乘的形式的种类个数是(a1+1)*(a2+1)*……*(an+1) 【不细讲了,你可以自己去写几个找找规律】

那么N^2=p1^2a1 * p2^2a2 *……*pn^2an

此时,种类数即为(2a1+1)*(2a2+1)*……*(2an+1)  

这个问题就迎刃而解了,接下来就是求底和幂的事情了。

需要特别注意的是当N<2时,是无法整数拆分的,也就是种类数为0


#include <iostream> 
#include <cmath> 
using namespace std; 
#define MAXI 20 
struct yinshu 
{ 
    int di; 
    int mi; 
}; 
struct Div 
{ 
    int xiangshu; 
    int xdi[MAXI]; 
    int xmi[MAXI]; 
}; 
Div getpN(int m); 
void vout(Div pN); 
yinshu getOne(int yin,int& m); 
int main() 
{ 
    int ncase,n,i; 
    cin>>ncase; 
    Div pN; 
    while(ncase--) 
    { 
        cin>>n; 
        pN=getpN(n); 
        vout(pN); 
    } 
    return 0; 
} 
Div getpN(int m) 
{ 
    int i,j; 
    Div pans; 
    yinshu x; 
    if(m<2) 
    { 
        pans.xdi[0]=1; 
        pans.xmi[0]=0; 
        pans.xiangshu=0; 
        return pans; 
    } 
    int uplimit=(int)sqrt(m*1.0); 
    i=2; 
    j=0; 
    while(i<=uplimit) 
    { 

        if(m%i==0) 
        { 
            x=getOne(i,m); 
            pans.xdi[j]=x.di; 
            pans.xmi[j]=x.mi; 
            j++; 
            uplimit=(int)sqrt(1.0*m); 
        } 
        i++; 
    } 
    if(m>1) 
    { 
        pans.xdi[j]=m; 
        pans.xmi[j]=1; 
        j++; 
    } 
    pans.xiangshu=j; 
    return pans; 
} 
void vout(Div pN) 
{ 
    int i; 
    int ans=1; 
    for(i=0;i<pN.xiangshu;i++) 
    { 
        ans*=(pN.xmi[i]*2+1); 
    } 
    cout<<ans<<endl; 
} 
yinshu getOne(int yin,int& m) 
{ 
    yinshu x; 
    x.di=yin; 
    x.mi=0; 
    while(m%yin==0) 
    { 
        x.mi++; 
        m/=yin; 
    } 
    return x; 
} 



版权声明:本文为博主原创文章,未经博主允许不得转载。

整数拆分问题详解

问题:  给定一个整数n,要找出n能拆分成多少种不同的若干个数的和与乘积的形式。比如:     4=4                   12=1*12     4=1+3             ...
  • pipisorry
  • pipisorry
  • 2014年07月16日 16:06
  • 2509

整数拆分问题的四种解法

经典整数拆分的问题的算法设计与实现,分别给出递归版本、动态规划版本、五边形数定理版本、母函数版本四种算法设计与实现...
  • u011889952
  • u011889952
  • 2015年04月01日 21:17
  • 9205

整数拆分问题

整数拆分问题 2013-02-28 21:41:51 分类: C/C++ 整数分拆[编辑] 维基百科,自由的百科全书 一个正...
  • pi9nc
  • pi9nc
  • 2013年09月30日 15:07
  • 3058

算法回忆录:母函数解决整数拆分

省略了很多内容,所以需要一定基础才可阅读。主要为了说清母函数如何解决此问题。 整数拆分: 1、整数拆分可以理解为苹果放盘子问题(把N个苹果放在M个盘子里有多少种方法),只是这是相当于把N个苹果放在...
  • u013293644
  • u013293644
  • 2016年04月26日 15:57
  • 689

整数分解问题(二)

我们一起来看看这个问题吧!上个问题我们已经接触过整数分解了,那么你有没有一定的了解了吗? 题意:输出N的整数分解 有没有感觉比上一题简单多了,没有脑筋急转和,题意粗暴明了,唯一让人头疼的是,怎么输...
  • qq_25931695
  • qq_25931695
  • 2017年01月03日 11:21
  • 377

算法-整数拆分

正整数n可以拆成若干个正整数之和,考虑拆分方案的个数。 输入 5 输出 5 首先证明: g(i,j)= g(i,j-1)+ g(i-j,j) (1)     如果j>i,则g(i,j)=g(...
  • gddxmmxf
  • gddxmmxf
  • 2017年03月29日 13:04
  • 400

第一讲、整数划分(回溯实现)

/**  *   * @author chenzhuzuo  * 回溯法解决数字拆分问题  * 问题描述:  * 整数的分划问题。  如,对于正整数n=6,可以分划为:  6  5+1...
  • u013447515
  • u013447515
  • 2016年01月30日 23:56
  • 308

邝斌的ACM模板(整数拆分)

本博客整理自邝斌的ACM模板 2.11、 整数拆分 HDU 4651 const int MOD = 1e9+7; int dp[100010]; void init() { memse...
  • qq_38576126
  • qq_38576126
  • 2017年09月05日 19:09
  • 142

动态规划解决整数划分的问题

前几天去华为做机试,遇到一个整数划分的问题,题目是:现有1,2,5,10,20,50,100 元这几种钱币,问给定n元能有多少种分配方式。例如n=4时,有1+1+1+1  ,1+2+1 , 2+2 三...
  • sxiaobei
  • sxiaobei
  • 2015年07月08日 01:00
  • 1296

母函数理解及整数拆分

母函数的定义以及整数拆分模板 母函数(Generating function)详解 分类: 母函数 2012-08-12 20:33 899人阅读 评论(0) 收藏 举报 ...
  • fsqfang
  • fsqfang
  • 2014年08月04日 11:21
  • 652
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:整数拆分问题(1)
举报原因:
原因补充:

(最多只允许输入30个字)