• ACM题目————字串数


    Description

    一个A和两个B一共可以组成三种字符串:"ABB","BAB","BBA".
    给定若干字母和它们相应的个数,计算一共可以组成多少个不同的字符串.
     

    Input

    每组测试数据分两行,第一行为n(1<=n<=26),表示不同字母的个数,第二行为n个数A1,A2,...,An(1<=Ai<=12),表示每种字母的个数.测试数据以n=0为结束.
     

    Output

    对于每一组测试数据,输出一个m,表示一共有多少种字符串.
     

    Sample Input

    2 1 2 3 2 2 2 0
     

    Sample Output

    3 90

    可以轻易推出公式 :(n1+n2+n3+...nn)!/(n1!*n2!*...*nn!);

    因为15!还在long long的范围之内,可以先定义一个数组f[15]保存1~15的阶乘,接着就是将(n1+n2+n3+...nn)!计算出来并存到数组内,接着就是大数除法了(相当于一个大数除一个小数)。

    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <cstdio>
    #include <cctype>
    #include <cstdlib>
    #include <stack>
    #include <cmath>
    #include <string>
    #include <queue>
    
    using namespace std;
    #define SIZE 30
    typedef long long ll ;
    int d[SIZE] ;
    int ans[1000] , f[15];
    void multiply(int c){
        ans[0] = ans[1] = 1 ;
        for(int i = 2 ; i <= c ; ++i){
            int r = 0 ;
            for(int j = 1 ; j <= ans[0] ; ++j){
                ans[j] *= i ;
                ans[j] += r ;
                r = ans[j]/10 ;
                ans[j] %= 10  ;
            }
            if(r != 0){
                while(r){
                    ans[ans[0]+1] += r%10 ;
                    ans[0] = ans[0]+1 ;
                    r /= 10 ;
                }
            }
        }
    }
    
    void divide(int n){
        for(int i = 0 ; i < n ; ++i){
            if(d[i] == 1) continue ;
            ll r = 0 ;
            for(int j = ans[0] ; j > 0 ; --j){
                r = r*10 + ans[j] ;
                ans[j] = (int)(r/f[d[i]]) ;
                r %= f[d[i]] ;
            }
            int j = ans[0] ;
            while(!ans[j--]) ;
            ans[0] = j+1 ;
        }
    }
    
    int main(){
        int n ;
        f[0] = f[1] = 1 ;
        for(int i = 2 ; i < 15 ; ++i)
            f[i] = f[i-1]*i ;
        while(scanf("%d",&n) && n){
            int c = 0; 
            memset(ans,0,sizeof(ans)) ;
            for(int i = 0 ; i < n ; ++i){
                scanf("%d",&d[i]) ;
                c += d[i] ;
            }
            multiply(c) ;
            divide(n) ;
            for(int i = ans[0] ; i > 0 ; --i)
                printf("%d",ans[i]) ;
            puts("") ;
        }
        return 0 ;
    }         

     2017-3-4再做这道题,用了Java~~哈哈

    import java.math.BigInteger;
    
    /**
     * 
     * @author Asimple
     * 
     */
    
    import java.util.Scanner;
    public class Main{
        static Scanner sc = new Scanner(System.in);
        public static void main(String[] args) {
            int n;
            while( sc.hasNext() ) {
                n = sc.nextInt();
                if( n == 0 ) break;
                int sum = 0;
                BigInteger a = BigInteger.valueOf(1);
                for(int i=0; i<n; i++) {
                    int num = sc.nextInt();
                    sum += num;
                    a = a.multiply(dd(num));
                }
                BigInteger b = dd(sum);
                b = b.divide(a);
                System.out.println(b.toString());
            }
        }
        
        public static BigInteger dd(int x) {
            BigInteger a = BigInteger.valueOf(1) ;
            for(int i=2; i<=x; i++) {
                a = a.multiply(BigInteger.valueOf(i));
            }
            return a;
        }
    }
    低调做人,高调做事。
  • 相关阅读:
    Linux下ps -ef 和 ps aux的区别
    oracle exp imp日常使用
    oracle 切换用户操作--or--sys用户密码忘记
    widows本地-xshell实现远程连接linux服务器图形界面
    oracle ASM安装过程中UDEV实现磁盘绑定
    Oracle修改指定表空间为自动扩展
    Oracle 扩展表空间大小的几种方式
    本地主机不安装oracle客户端--访问远程oracle数据库
    解决ubuntu安装系统默认没有创建root用户
    解决 ORA-27102: out of memory
  • 原文地址:https://www.cnblogs.com/Asimple/p/5698995.html
Copyright © 2020-2023  润新知