首页 > 代码库 > hdu1261(高精度+组合公式的应用)

hdu1261(高精度+组合公式的应用)

题目意思:

      给定若干字母和它们相应的个数,计算可以组成多少个不同的字符

http://acm.hdu.edu.cn/showproblem.php?pid=1261


题目分析:

      组合公式的直接应用,s!/(ai!) s:字符总数 ai:第i个字符的个数,用数组实现高精度的组合公式

      不要直接求是S!的阶乘,那样会超时,需要上下同时求,约去最大公约数,在将剩下的值模拟相乘


AC代码:

/**
 *s!/(ai!) s:字符总数 ai:第i个字符的个数
 *(高精度)
 */
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
int cmp(int a,int b){
    return a>b;
}
int gcd(int a,int b){
    if(b==0) return a;
    else return gcd(b,a%b);
}
int main()
{
    int n,a[30],sum[501];//sun储存结果
    int s2[400],b[27][15];//存储i便于计算
    while(cin>>n&&n){

        int i,j,k;
        int s=0;
        for(i=1;i<=n;i++){
            cin>>a[i];
            s+=a[i];
        }
        for(i=1;i<=s;i++){//记录所有个数
            s2[i]=i;
        }

        for(k=1;k<=n;k++){
            for(j=2;j<=a[k];j++){
                int m=j;
                while(m>1){
                    for(i=1;i<=s;i++){
                        int m1=gcd(s2[i],m);
                        m=m/m1;
                        s2[i]=s2[i]/m1;
                    }
                }
            }
        }
        memset(sum,0,sizeof(sum));
        //cout<<m<<endl;
        sum[0]=1;
        for(i=1;i<=s;i++){//模拟相乘没有约去的值
            //cout<<s2[i]<<" ";
            int flag=0;
            if(s2[i]!=1) for(j=0;j<=500;j++){
               int ss=sum[j]*s2[i]+flag;
               sum[j]=ss%10;
               flag=ss/10;
            }
            //s1*=s2[i];
        }

        for(i=500;!sum[i];i--);
        //cout<<i<<endl;
        for(j=i;j>=0;j--){
            cout<<sum[j];
        }
        cout<<endl;
    }
    return 0;
}




hdu1261(高精度+组合公式的应用)