大白书—数学基础—基础题

*最小公倍数(Benefit,uva10943)

输入两个整数A和C(1<=A,C<=10^7),求最小的整数B使得LCM(A,B)=C。如果无解,输出“NO SOLUTION”。

分析:

lcm(a,b)=a*b/gcd(a,b),为了避免公共部分被消掉,b需要取满a未取满的部分。

初始b=c/a,然后a不断除以gcd(a,b),b不断乘以gcd(a,b),直到gcd(a,b)=1.


*lcm的个数(lcm cardinality, uva10892)

输入正整数n,(n<=2 000 000 000),统计有多少对正整数a<=b,满足lcm(a,b)=n。比如有8对正整数满足lcm(a,b)=12,即(1,12)(2,12)(3,12)(4,12)(6,12)(12,12)(3,4)(4,6)。输出n和满足条件的整数对数。

注意:约数的个数较少,即使O(n^2)的复杂度也可以很快求解出来。直接枚举约数,暴力计算个数即可。


**排列之和(add again ,uva11076)

输入n个数字(1<=n<=12),这些数字的任何一种排列都是一个整数。你的任务是求出所有这些整数之和。比如3个数字2,2,4能组成3个整数224,242,422,他们的和是888.

分析:对于某个数字来说,它出现在每一位的概率相同,只需求出每位上出现的次数,乘以1111~~~111即可。

代码:

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<queue>
#include<stack>
#define MOD 1000000009
using namespace std;
int main()
{
    unsigned long long sum,num,s1,s2;
    int n,a[30],m,i,j;
    while(scanf("%d",&n)&&n)
    {
        sum=0;
        num=1;
        s1=s2=0;
        memset(a,0,sizeof(a));
        for(i=1;i<=n;i++)
        {
            scanf("%d",&m);
            a[m]++;
            num*=i;
            s1=s1*10+1;
        }
        for(i=0;i<10;i++)
        {
            for(j=2;j<=a[i];j++)
                num/=j;
        }
        for(i=0;i<10;i++)
        {
            sum+=i*a[i]*num/n;
        }
        sum*=s1;
        printf("%llu\n",sum);
    }
    return 0;
}




你可能感兴趣的:(数学基础)