题目链接:K. Key Storage
题目大意
给你一个数让你求出这个数除以2,除以3,递推下去,直到除数为0的时候得到的余数相同的集合相同的数有多少个。
解题思路
大佬博客链接
很好的一道排列组合问题。中间还有一些小的细节看代码吧。
代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int mx=101;
int a[mx];
// 求组合数
ll C(ll n,ll m){
ll res=1;
m=min(n-m,m);
for(int i=0;i<m;i++){
res=res*(n-i)/(i+1);
}
return res;
}
ll slove(ll x){
ll res=1;
ll sum=0;
/*
这里之所以是 x+1是因为 防止第二次处理的造成差错
比如说 4 余数集合为 0 2;
第一次计算后得到的结果是 1;
再次计算的时候 cnt变成 1了,如果还是从 cnt开始就返回1
造成结果为负值。
*/
for(int i=x+1;i;i--){
if(x+1-i-sum<a[i]) return 0;
if(a[i]){
res*=C(x+1-i-sum,a[i]);
sum+=a[i];
}
}
return res;
}
int main(){
int t;cin>>t;
ll x;
while(t--){
cin>>x;
int cnt=0;
ll i=2;
while(x){
a[x%i]++;
x/=i;
i++;cnt++;
}
ll ans=slove(cnt);
if(a[0]){
a[0]--;
ans-=slove(cnt-1);
}
for(int i=0;i<=cnt;i++)
a[i]=0;
cout<<ans-1<<"\n";
}
return 0;
}