UVa11076

11076 Add Again
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
31
2 3
31
1 2
0
Sample Output
1332
444

题意:
       输入n个数字,这些数字的任意排列总是一个数。你的任务是求出所有这些数的和。

分析:

其实,输入的每个数字在每一位出现的概率都是相同的,于是,我们可以先计算出所有输入数字的平均值A。而可重复的排列数就是P=n!/(n1!*n2!*…*nk!)最终的答案就是11…1(n个1)*A*P。

 1 #include <cstdio>
 2 #include <cstring>
 3 #define ll long long
 4 int N;
 5 ll factorial[13];
 6 int num[10];
 7 const ll one[13] = {
 8     0, 1, 11, 111, 1111, 11111, 111111, 1111111, 11111111,
 9     111111111, 1111111111, 11111111111, 111111111111
10 };
11 void cal_factorial(){
12     factorial[0] = 1,factorial[1] = 1;
13     for(int i = 2 ; i <= 12 ; i++) factorial[i] = i * factorial[i - 1];
14 }
15 int main(){
16     cal_factorial();
17     int sum = 0;
18     while(scanf("%d",&N) == 1 && N){
19         sum = 0;
20         memset(num,0,sizeof num);
21         for(int i = 0 ; i < N ; i++){
22             int tmp; scanf("%d",&tmp);
23             num[tmp]++,sum += tmp;
24         }
25         ll ans = factorial[N - 1] * sum;
26         for(int i = 0 ; i < 10 ; i++) ans /= factorial[num[i]]; // 平均数需要除以N,将分子上N
27         printf("%lld\n",ans * one[N]);
28     }
29     return 0;
30 }

时间: 2024-10-11 01:01:04

UVa11076的相关文章

排列之和 UVa11076

1.题目描述:点击打开链接 2.解题思路:本题利用平均数的思想解决.由于每个数出现在任何一位的总的次数都是相同的,因此可以等效为它们的平均数出现的次数,而出现的次数就是重复排列的组合数,最后再乘以n个1即可得到答案.比如一个序列是{1,1,2},那么平均数就是(1+1+2)/3=4/3.出现的次数就是P(3,3)/P(2,2)=3,一共有3个1,那么ans=(4/3)*3*111=444. 3.代码: #define _CRT_SECURE_NO_WARNINGS #include<iostre

减治求有重复元素的全排列

求n个元素的全排列的所有解可以用减治法:每次拎出一个数做前缀,对剩下的元素再求全排列,直至只剩一个元素.代码源自<算法分析与设计(王晓东)>,复杂度O(n2) 1 //输出k~m的所有全排列 2 void perm(int k,int m) 3 { 4 if(k==m) 5 { 6 for(int i=0;i<=m;i++) 7 printf("%d ", list[i]); 8 printf("\n"); 9 }else 10 { 11 for(

《算法竞赛入门经典——训练指南》第二章题库

UVa特别题库 UVa网站专门为本书设立的分类题库配合,方便读者提交: http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=442 注意,下面注有"extra"的习题并没有在书中出现,但在上面的特别题库中有,属于附加习题. 基础练习 (Basic Problems) UVa11388 GCD LCM UVa11889 Benefit UVa10943 How do y