Luogu 4163

题目分析:
-
这个题要求的排列是不能重复的,所有我们先假定的每位数不相等,最后统计答案数去掉重复的就
-
考虑枚举排列的过程:
有一个,我们已经排列到了
当我们把加进来时,变成了,相当于就是
而余数又会怎么变化呢?
% -
我们定义,
-
边界
-
状态转移:
%
Code:
#include <bits/stdc++.h>
using namespace std;
#define maxd 1010
#define maxn 20
#define max_size 1100
int a[maxn],T,d,n,f[max_size][maxd],cnt[maxn];
char s[maxn];
inline int read_() {
int x=0,f=1;
char c=getchar();
while(c<'0'||c>'9') {
if(c=='-') f=-1;
c=getchar();
}
while(c>='0'&&c<='9') {
x=(x<<1)+(x<<3)+c-'0';
c=getchar();
}
return x*f;
}
inline void clean_() {
memset(f,0,sizeof(f));
memset(cnt,0,sizeof(cnt));
}
inline void DP_() {
f[0][0]=1;
for(int i=0;i<(1<<n);++i) {
for(int j=0;j<d;++j) {
for(int k=1;k<=n;++k) {
if( ! ( i & (1<<(k-1)) ) ) {
f[i|(1<<(k-1))][(j*10+a[k])%d]+=f[i][j];
}
}
}
}
int ans=f[(1<<n)-1][0];
for(int i=0;i<=9;++i) {
for(int j=2;j<=cnt[i];++j) {
ans/=j;
}
}
printf("%d\n",ans);
}
void readda_() {
T=read_();
while(T--) {
clean_();
scanf("%s",s);
d=read_();
n=strlen(s);
for(int i=0;i<n;++i) {
a[i+1]=s[i]-'0';
++cnt[a[i+1]];
}
DP_();
}
}
int main() {
freopen("a.txt","r",stdin);
readda_();
return 0;
}
来源:CSDN
作者:小元勋
链接:https://blog.csdn.net/weixin_44574520/article/details/100104081