zoukankan      html  css  js  c++  java
  • hdu4497 (正数分解定理+排列组合)

    题目如下:

    GCD and LCM

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)
    Total Submission(s): 2990    Accepted Submission(s): 1310


    Problem Description
    Given two positive integers G and L, could you tell me how many solutions of (x, y, z) there are, satisfying that gcd(x, y, z) = G and lcm(x, y, z) = L? 
    Note, gcd(x, y, z) means the greatest common divisor of x, y and z, while lcm(x, y, z) means the least common multiple of x, y and z. 
    Note 2, (1, 2, 3) and (1, 3, 2) are two different solutions.
     
    Input
    First line comes an integer T (T <= 12), telling the number of test cases. 
    The next T lines, each contains two positive 32-bit signed integers, G and L. 
    It’s guaranteed that each answer will fit in a 32-bit signed integer.
     
    Output
    For each test case, print one line with the number of solutions satisfying the conditions above.
     
    Sample Input
    2 6 72 7 33
     
    Sample Output
    72 0
     告诉了三个数的最大公约数和最小公倍数,要你求出这三个数字有多少种可能(次序不同,排列不同)
    先想想两个数字之间的关系是什么?
    如果L/G!=0,证明找不到这样的三个数字;
    如果L/G==0,通过分析得到:gcd(x/g,y/g,z/g)=1&&lcm(x/g,y/g,z/g)=L/G,所以问题就转换成了分解L/G,根据正数分解唯一定理,我们可以把这个数分解为:

    假设L/G = p1^t1 * p2^t2 *````* pn^tn。

    满足上面条件的x,y,z一定为这样的形式。

    x' = p1^i1 * p2^i2 *```* pn^in.

    y' = p1^j1 * p2^j2 * ```*pn^jn.

    z' = p1^k1 * p2^k2 * ```*pn^kn.

    为了满足上面的条件,对于p1,一定有max(i1,j1,k1) = t1.min(i1,j1,k1) =0;则当选定第一个数为0,第二个数为t1时,第三个数可以为0-t1,又由于有顺序的,只有

    (0,t1,t1) 和(0,t1,0)这两种情形根据顺序只能产生四种结果,其他的由于三个数都不一样,一定能产生6种,所以最后产生了6*(t1-1)+3*2 = 6*t1种,根据乘法原理以及关于素数分解的唯一性,反过来,素数组合必然也是唯一的数,一共有6*t1 * 6*t2 *`````*6*tn种选法。

    其他的同理。
    代码如下:
     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 //const int  MAXN=100000;
     4 #define maxn 1000005
     5 int cnt[maxn];
     6 long long ans;
     7 void solve(int n)
     8 {
     9     memset(cnt,0,sizeof(cnt));
    10     int t=sqrt(n*1.0+0.5);
    11     for(int i=2;i<=t;i++)
    12     {
    13     if(n%i==0)
    14     {
    15         while(n%i==0)
    16         {
    17             cnt[i]++;
    18             n/=i;
    19         }
    20     }
    21     }
    22     //int ans=1;
    23     if(n!=1)//特殊地方处理,注意一下。列举一下,比如3
    24         ans=6;
    25     else ans=1;
    26     for(int i=2;i<=t;i++)
    27     {
    28         if(cnt[i])
    29             ans=ans*6*cnt[i];
    30     }
    31 }
    32 
    33 
    34 
    35 
    36 
    37 
    38 
    39 int main()
    40 {
    41 int t ;
    42 scanf("%d",&t);
    43 while(t--)
    44     {
    45         ans=1;
    46      int n,m;
    47     scanf("%d %d",&n,&m);
    48 
    49         if(m%n)
    50             cout<<0<<endl;
    51         else
    52         {
    53             n=m/n;
    54             solve(n);
    55             printf("%I64d
    ",ans);
    56         }
    57 
    58 
    59 }
    60 
    61 
    62 
    63 
    64 
    65     return 0;
    66 }
  • 相关阅读:
    java类型比较_Java数据类型的比较
    学习方法-1:海绵学习法
    性能测试:TPS和QPS的区别
    代码反思
    网站TLS升级 1.0&1.1--1.2
    Mysql常用语法
    初级测试工程师面试指南
    postman实战之断言
    postman预处理脚本实战
    什么是HTTP超文本协议
  • 原文地址:https://www.cnblogs.com/renxin123/p/8612071.html
Copyright © 2011-2022 走看看