CF991E Bus Number

原题链接:http://codeforces.com/problemset/problem/991/E

Bus Number

This night wasn’t easy on Vasya. His favorite team lost, and he didn’t find himself victorious either — although he played perfectly, his teammates let him down every time. He had to win at least one more time, but the losestreak only grew longer and longer… It’s no wonder he didn’t get any sleep this night at all.

In the morning, Vasya was waiting the bus to the university on the bus stop. Vasya’s thoughts were hazy and so he couldn’t remember the right bus’ number quite right and got onto the bus with the number n n .

In the bus, Vasya thought that he could get the order of the digits in the number of the bus wrong. Futhermore, he could “see” some digits several times, but the digits he saw were definitely in the real number of the bus. For example, if Vasya saw the number 2028, it could mean that the real bus number could be 2028, 8022, 2820 or just 820. However, numbers 80, 22208, 52 definitely couldn’t be the number of the bus. Also, real bus number couldn’t start with the digit 0, this meaning that, for example, number 082 couldn’t be the real bus number too.

Given n, determine the total number of possible bus number variants.

Input

The first line contains one integer n(1n1018) n ( 1 ≤ n ≤ 10 18 ) — the number of the bus that was seen by Vasya. It is guaranteed that this number does not start with 0 0 .

Output

Output a single integer — the amount of possible variants of the real bus number.

Examples
input

97

output

2

input

2028

output

13

Note

In the first sample, only variants 97 and 79 79 are possible.

In the second sample, the variants (in the increasing order) are the following: 208,280,802,820,2028,2082,2208,2280,2802,2820,8022,8202,8220 208 , 280 , 802 , 820 , 2028 , 2082 , 2208 , 2280 , 2802 , 2820 , 8022 , 8202 , 8220 .

题解

直接枚举每个数字的出现次数,然后组合数求解,用总情况减去 0 0 <script type="math/tex" id="MathJax-Element-82">0</script>开头的情况。

代码
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int M=20;
int cot[M],num[M],n;
char ch[M];
ll fac[M],ans;
ll C(int n,int m){return fac[n]/fac[n-m]/fac[m];}
void check()
{
    int sum,tot=0;ll tmp=1;
    for(int i=0;i<=9;++i)tot+=num[i];sum=tot;
    for(int i=0;i<=9;++i)tmp*=C(sum,num[i]),sum-=num[i];
    if(num[0])tmp-=tmp*num[0]/tot;
    ans+=tmp;
}
void dfs(int v)
{
    if(v>9){check();return;}
    if(!cot[v])dfs(v+1);
    for(int i=1;i<=cot[v];++i)num[v]=i,dfs(v+1);
}
void in(){scanf("%s",ch+1);}
void ac()
{
    n=strlen(ch+1);for(int i=1;i<=n;++i)++cot[ch[i]-'0'];
    fac[0]=1;for(int i=1;i<=n;++i)fac[i]=fac[i-1]*i;
    dfs(0);printf("%lld",ans);
}
int main(){in();ac();}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ShadyPi

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值