首页 > 代码库 > UVA 11076 Add Again

UVA 11076 Add Again

题目链接:UVA-33478

题意为给定n个数,求这n个数能组成的所有不同的排列组成的数字的和。

思路:发现对于任意一个数字,其在每一位出现的次数是相同的。换言之,所有数字的每一位相加的和是相同的。

所以我们只需求出这个“和”即可。

考虑任意一位i,假设我们在i位放置x,则对应\( (n-1)! / ( d_0! * d_1! * ... * d_x! * ... * d_9! ) \)种情况。

所以我们要求的“和”等于\(\sum_x x * (n-1)! / ( d_0! * d_1! * ... * d_x! * ... * d_9! )\)。

代码如下:

 1 #include"cstdio"
 2 #include"iostream"
 3 #include"cstring"
 4 #include"algorithm"
 5 #include"cstdlib"
 6 #include"vector"
 7 #include"set"
 8 using namespace std;
 9 typedef unsigned long long LL;
10 const LL MAXN=1e5;
11 
12 LL fact[20];
13 int main()
14 {
15 #ifdef LOCAL
16     freopen("in.txt","r",stdin);
17     //freopen("out.txt","w",stdout);
18 #endif
19     fact[0]=1;
20     for(LL i=1;i<13;i++)
21         fact[i]=fact[i-1]*i;
22     LL n;
23     while(scanf("%lld",&n)!=EOF && n)
24     {
25         LL d[10];
26         memset(d,0,sizeof(d));
27         for(LL i=1;i<=n;i++)
28         {
29             LL tmp;
30             scanf("%lld",&tmp);
31             d[tmp]++;
32         }
33         LL r=0;
34         for(LL i=0;i<10;i++)
35             if(d[i])
36             {
37                 LL tmp=fact[n-1];
38                 for(LL j=0;j<10;j++)
39                 {
40                     if(j==i) tmp/=fact[d[j]-1];
41                     else tmp/=fact[d[j]];
42                 }
43                 r+=tmp*i;
44             }
45         LL ans=0;
46         for(LL i=1;i<=n;i++)
47         {
48             ans*=10;
49             ans+=r;
50         }
51         printf("%lld\n",ans);
52     }
53     return 0;
54 }

 

UVA 11076 Add Again