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 }