题解:dp数组记录当前数字和%d以及用了哪些数字
#include<iostream>
#include<cstring>
#include<cstdio>
#define N 11
#define D 1010
using namespace std;
int fac[10],b[10];char s[N];
int dp[1<<N][D],a[N];
inline int toi(char ch)
{
return ch^'0';
}
inline int getv(int x,int p)
{
return (x&(1<<(p-1)))>>(p-1);
}
inline int updv(int x,int p)
{
return x|(1<<(p-1));
}
int main()
{
int T;scanf("%d",&T);
fac[0]=1;
for(int i=1;i<=9;i++)
fac[i]=fac[i-1]*i;
while(T--)
{
scanf("%s",s+1);
int n=strlen(s+1);
for(int i=1;i<=n;i++)
a[i]=toi(s[i]);
memset(b,0,sizeof(b));
for(int i=1;i<=n;i++)
b[a[i]]++;
int all=(1<<n)-1,d;
scanf("%d",&d);
for(int i=0;i<=all;i++)
for(int s=0;s<d;s++)
dp[i][s]=0;
dp[0][0]=1;
for(int i=0;i<all;i++)
for(int s=0;s<d;s++)
for(int j=1;j<=n;j++)
if(!getv(i,j)) dp[updv(i,j)][(s*10+a[j])%d]+=dp[i][s];
for(int i=0;i<=9;i++)
dp[all][0]/=fac[b[i]];
printf("%d\n",dp[all][0]);
}
return 0;
}