UVa 11076 - Add Again (排列之和 组合数学)

来源:互联网 发布:手机后期ps软件 编辑:程序博客网 时间:2024/05/01 18:14

Problem C
Add Again
Input: 
Standard Input

Output: Standard Output

 

Summation of sequence of integers is always a common problem in Computer Science. Rather than computing blindly, some intelligent techniques make the task simpler. Here you have to find the summation of a sequence of integers. The sequence is an interesting one and it is the all possible permutations of a given set of digits. For example, if the digits are <1 2 3>, then six possible permutations are <123>, <132>, <213>, <231>, <312>, <321> and the sum of them is 1332.

 

Input

Each input set will start with a positive integer N (1≤N≤12). The next line will contain N decimal digits. Input will be terminated by N=0. There will be at most 20000 test set.

 

Output

For each test set, there should be a one line output containing the summation. The value will fit in 64-bit unsigned integer.

 

Sample Input                             Output for Sample Input

3

1 2 3

3

1 1 2

0

 

1332

444

 


Problemsetter: Md. Kamruzzaman

Special Thanks: Shahriar Manzoor

 

 


题意:

输入n个数字,这些数字的任何一种排列都是一个整数,你的任务是求出所有这些整数之和。


对于m个数,要求他的和,可以像这样求

对于每一位i,求m个数第i为上的和然后乘第i位相应的权值10^i(i从0开始)

对于第i位j出现的方法数则是除去一个j后的其他数的排列方法数


这个题unsigned long long 也会超

但是 unsigned long long / long long 也能过

数据没有这么大?



#include <cstdio>#include <iostream>#include <vector>#include <algorithm>#include <cstring>#include <string>#include <map>#include <cmath>#include <queue>#include <set>using namespace std;//#define WIN#ifdef WINtypedef __int64 LL;#define iform "%I64d"#define oform "%I64d\n"#define oform1 "%I64d"#elsetypedef long long LL;#define iform "%lld"#define oform "%lld\n"#define oform1 "%lld"#endif#define S64I(a) scanf(iform, &(a))#define P64I(a) printf(oform, (a))#define P64I1(a) printf(oform1, (a))#define REP(i, n) for(int (i)=0; (i)<n; (i)++)#define REP1(i, n) for(int (i)=1; (i)<=(n); (i)++)#define FOR(i, s, t) for(int (i)=(s); (i)<=(t); (i)++)const int INF = 0x3f3f3f3f;const double eps = 10e-9;const double PI = (4.0*atan(1.0));int vis[10];unsigned long long C[20][20];void init(int n) {    memset(C, 0, sizeof(C));    C[0][0] = 1;    for(int i=1; i<=n; i++) {        C[i][0] = C[i][i] = 1;        for(int j=1; j<i; j++) {            C[i][j] = C[i-1][j-1] + C[i-1][j];        }    }}int main() {    int n;    init(15);    while(scanf("%d", &n) != EOF && n) {        int sum = 0;        memset(vis, 0, sizeof(vis));        for(int i=0; i<n; i++) {            int t;            scanf("%d", &t);            vis[t]++;            sum += t;        }        unsigned long long p10 = 1;        unsigned long long ans = 0;        for(int i=0; i<n; i++) {            for(int j=1; j<10; j++) if(vis[j]) {                vis[j]--;                int lev = n-1;                LL tt = 1;                for(int k=1; k<10; k++) if(vis[k]) {                    tt *= C[lev][vis[k]];                    lev -= vis[k];                }                ans += p10 * j * tt;                vis[j]++;            }            p10 *= 10;        }        cout<<ans<<endl;    }    return 0;}




0 0