数论 UVA 11076
这道题目的意思简单易懂说的是给你n个数(可能有重复相同的数字),列出他们所有排列的情况,再逐位相加,求出和,例如:给你1,2,3,则排列的情况为<123>, <132>, <213>, <231>, <312>, <321> ,则相加的和为1332。思路很好把握,但是需要比较扎实的数学基础,因为该问题的核心公式需要理解和记忆否则很难做出来。
这道题目的核心知识点是:多重集合排列(也叫不全相异元素全排列),这里有一个定理:设S是一个多重集合,其中有k种不同的元素,各种元素的个数分别是:n1,n2,…nk。设S中所有元素的个数是n=n1+n2+...+nk。则S的全排列数(n-排列)为:n!/(n1!*n2!*n3!*...nk!)。
证明:通过观察和分析,我们会发现S的全排列中的每一种情况都包含了S中的每一个元素,并且每个元素在每一种情况中出现的次数都等于该种元素所拥有的元素个数。因此我们可以构造这样的一个排列,n个位置,n个元素,元素中存在同类元素(也可以看做是相同元素)。首先,我们为第1类的n1个元素指定位置,那么有C(n,n1)种情况。处理完后,我们接着对第2类的n2个元素指定位置,那么有C(n-n1,n2)种情况。以此类推,我们可以得出第k类的nk个元素指定位置有C(n-n1-n2-...-nk-1,nk)种情况。根据乘法原理,排列元素的的方法数为C(n,n1)*C(n-n1,n2)*...*C(n-n1-n2-..nk-1,nk)=n!/n1!(n-n1)!*(n-n1)!/n2!(n-n1-n2)!*...化简后n!/(n1!n2!...nk!0!)=n!/(n1!n2!...nk!)。
到这里,这道题目已经完成了70%了,剩下的30%则是对问题的又一个转化。我们知道,在全排列中,任意一个数字出现在各个位置上的次数是相同的,那么求和后,每一位上的数字的和都是每种数字出现的次数乘上每种数字的值然后求和,之后只需要乘上相应数位上的10^k并且考虑好进位就能算出结果。求每一位上每种数字出现的次数,则需要通过分析来化简,因为每一位上每种数字出现的次数是相同的,这是通过分析与观察得出的,那么我们只需要求出某一位上每种数字出现的次数即可,然后算出这一位的总和,由于每一位上的总共和都相同,只不过需要解决进位和乘上的10的次方来保证数位。值得一提的是,这道题目的数据会很大,存储答案的变量最好用unsigned long long 来存储。
#include <iostream>
#include <cmath>
#include <cstdio>
#include <cstring>
using namespace std;
int jc[15],num[12],re[15];
int main()
{
int n,i;
for(jc[0]=i=1;i<15;i++)
jc[i]=jc[i-1]*i;
while(scanf("%d",&n)!=EOF&&n)
{
memset(num,0,sizeof(num));
int t,m=0;
for(i=0;i<n;i++)
{
scanf("%d",&t);
num[t]++;
if(num[t]==1)
re[m++]=t;
}
unsigned long long temp,sum=0;
int j;
for(i=0;i<m;i++)
{
temp=jc[num[re[i]]-1];
for(j=0;j<m;j++)//计算某一位上的和,由于这一和值在每一位上都一样,所以只需要计算出一位即可。
{
if(j==i)
continue;
temp*=jc[num[re[j]]];
}
sum+=((jc[n-1]/temp)*re[i]);
}
temp=sum;
sum=0;
for(i=0;i<n;i++)
{
sum+=temp;
temp*=10;//将每一位的和还原到每一位上去。
}
cout<<sum<<endl;
}
return 0;
}
数论 UVA 11076的更多相关文章
- 【数论-数位统计】UVa 11076 - Add Again
Add AgainInput: Standard Input Output: Standard Output Summation of sequence of integers is always a ...
- Uva 11076 Add Again (数论+组合数学)
题意:给你N个数,求把他们的全排列加和为多少 思路:对于这道题,假设数字k1在第一位,然后求出剩下N-1位的排列数num1,我们就可以知道k1在第一位时 排列有多少种为kind1, 同理,假设数字k2 ...
- 数论 UVA 10780
数论题目.有关内容:整数质因数分解,N的阶乘质因数分解,整除的判断. 这道题的题意是给你两个数n.m,要求你求出n!所能整除的m^k的最大值的k是多少. 由于数据范围:1<m<5000,1 ...
- 数论 UVA 10943
这是一道关于组合数和隔板法的数论题目.题目说的是选出k个不同且不大于N的数字进行相加,要求这些数字之和等于N,结果要求输出这样的数有多少组.这里可以将问题利用隔板法来转换,那么题目的叙述可以转换成:这 ...
- 数论 UVA 11889
有关数论的题目,题目大意是给你两个数a和c,c为a和另一个数b的最小公倍数,要求你求出b的最小值.由最大公约数gcd(a,b)和最小公倍数lcm(a,b)之间的关系可知,lcm(a,b)*gcd(a, ...
- 数论 UVA 10791
这道题目是关于满足同意最小公倍数的所有数对中两数之和的最小值. 题目大意是给你一个数n,要求你求出在所有以n为最小公倍数的数对中两数之和的最小值. 方法:将n进行质因数分解,再将所有分解出的质因子加起 ...
- UVA 11076 - Add Again(组合)
题目链接 脑子抽了,看错题了,神奇的看成没有0了.主要问题把n个数插入m个相同的数,把m个数给分成1-m堆,然后插到n+1空里. #include <cstdio> #include &l ...
- 数论 UVA 11752
题目大意是在1~2^64-1的范围内找到所有符合条件的数,条件要求这个数字是两个或两个以上不同数字的幂,例如64=8^2=4^3. 对于这一题,分析是:如果一个满足这个条件的数字一定可以转换成i^k, ...
- 数论 UVA 11388
这道题是关于两个数的最大公约数和最小公倍数的题目.给你两个数字g,l,分别表示最大公约数和最小公倍数.要求你找到两个数a,b,要求这两个数的最大公约数和最小公倍数为所给的两个数.如果存在多组数字符合这 ...
随机推荐
- Scrum Meeting 7-20151209
任务安排 姓名 今日任务 明日任务 困难 董元财 服务器购买记录接口 请假(编译攻坚) 无 胡亚坤 发布记录和购买记录 请假(编译攻坚) 无 刘猛 完成Scrum Meeting 请假(编译攻坚) 无 ...
- [Prodinner项目]学习分享_第一部分_Model层
事先声明一下,小弟我是菜鸟一个,在研究大半天之后,基本会开发一些简单的功能了,特此分享一下,也为自己做一个笔记. 项目简介: MVC4 , EF5 , Code First , 多层架构 开发工具:V ...
- keyup与setInterval
<html><body> <input type="text" id="clock" size="35" /& ...
- redis 在32位系统安装以及使用
1.下载32位redis文件. http://pan.baidu.com/s/1eRIZPAE 我下载后的路径是:E:\Redis\Redis 里面的文件如图: 2.调取命令窗口 win+R,输入命 ...
- <!DOCTYPE> DTD基础
1.什么是DTD? DTD(Document Type Definition)是文档类型定义. 2.DTD有什么用? 约定文档格式,规定元素,元素属性,元素关系,标签,实体等. 3.DTD分类 DTD ...
- Docker中的镜像分层技术详解
早在集装箱没有出现的时候,码头上还有许多搬运的工人在搬运货物,在集装箱出现以后,码头上看到更多的不是工人,而且集装箱的搬运模式更加单一,更加高效,还有其他的好处,比如:货物多打包在集装箱里面,可以防止 ...
- C语言指针
我是搞java的,今年要找工作,参加笔试就必须要准备一些C/C++.算法.数据结构.操作系统.概率论的东西,浅谈一下我作为初学者对C指针的学习和理解. 一.*p 概念: 申明一个整形指针变量: int ...
- Android 之 log
android.util.Log常用方法: Log.v() VERBOSE 任何消息都会输出 Log.d() DEBUG 仅输出debug调试的意思,但他会输出上层的信息,过滤起来可以通过DD ...
- eclipse 本地项目提交到远程库以及从远程库中添加项目 ---git
本地项目提交到远程库 1.右击项目->team->share project 2.选择本地库 从远处库中的项目拉到本地 1.右击项目->import项目
- Android 图片圆角的设置
ImageView的scaleType的属性有好几种,分别是matrix(默认).center.centerCrop.centerInside.fitCenter.fitEnd.fitStart.fi ...