*最小公倍数(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; }