UVA 11076(数论 不全相异元素全排列)

题目链接:https://cn.vjudge.net/contest/269773?tdsourcetag=s_pcqq_aiomsg#problem/G

题意:给你N个数,求把他们的全排列加和为多少

参考https://www.cnblogs.com/hbutACMER/p/4235696.html

考虑任意一位i,假设我们在i位放置x,则对应(n−1)!/(d0!∗d1!∗...∗dx!∗...∗d9!)(n−1)!/(d0!∗d1!∗...∗dx!∗...∗d9!)种情况。

PS:前导0也算一种情况,举个栗子 

3

0 0 1

答案是1 1 1

#include<bits/stdc++.h>
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define limit(a,b) memset(a,b,sizeof a)
const int N=5e5+7;
const int INF = 0x3f3f3f3f;
const int mod=1e6;
ull f[20];
int b[N],a[N];
// 如何求重复数的全排列
//         元素表述:   a1,a1,...a1,   a2,a2,...a2,.......,an,an,...an
//         其中,a1的个数为N1,   a2的个数为N2,以此类推,总个数为M。
//
//         则可以证明不重复的排列种类的数目:   M!/(N1!*N2!*...*Nn!)
//然后这道题就可以转化成在任意一位i上当前值是a的组合数的情况为s,那么
//当前位所得的值为a*s,其余的数字情况一样处理
int main()
{
    int n;
    #ifndef ONLINE_JUDGE
    freopen("in.txt","r",stdin);
    #endif // ONLINE_JUDGE
    f[0]=1;
    rep(i,1,12) f[i]=i*f[i-1];
    while(scanf("%d",&n)!=EOF,n){
            limit(b,0);
            int cnt=0;//
        rep(i,1,n) {int t;
        scanf("%d",&t);
        b[t]++;
        if(b[t]==1) a[cnt++]=t;
        }
        ull ans=0;
        ull temp;
        rep(i,0,cnt-1){//因为每一位的情况是相同的,可以通过模拟发现,因此只需要求一位的情况就好
           temp=f[b[a[i]]-1];     //其他位那就相加移位就好。
            rep(j,0,cnt-1){
            if(i==j) continue;
            temp*=f[b[a[j]]];
            }
            ans+=(f[n-1]/temp)*a[i];
            }
            temp=ans;//每一位的总和
            ans=0;
        rep(i,0,n-1) ans+=temp,temp*=10;
        printf("%lld\n",ans);
        }
     return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值