lightoj 1158 - Anagram Division

Given a string s and a positive integer d you have to determine how many permutations of s are divisible by d.

Input

Input starts with an integer T (≤ 200), denoting the number of test cases.

Each case contains a string s (1 ≤ slength ≤ 10) and an integer d (1 ≤ d ≤ 1001)s will only contain decimal digits.

Output

For each case, print the case number and the number of permutations of s that are divisible by d.

Sample Input

Output for Sample Input

3

000 1

1234567890 1

123434 2

Case 1: 1

Case 2: 3628800

Case 3: 90



给你一个字符串,问你用这些数字能排列出多少种不同的数字能被d整除。

直接状压求出所有能被d整除的排列,然后再除以每个数字出现次数的阶乘,就是答案了。

DP的时候优化一点,就不会超时了。


#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define inf 1e9
#define endl '\n'
#define mod 100000007
#define LL long long

using namespace std;

int dp[1100][1100];

int main(void)
{
    int T,n,d,i,j,k;
    scanf("%d",&T);
    char s[15];
    int f[15],a[15],num[15];
    int cas =  1;
    f[0] = 1;
    for(i=1;i<=10;i++)
        f[i] = f[i-1]*i;
    while(T--)
    {
        scanf("%s%d",s,&d);
        n = strlen(s);
        memset(num,0,sizeof(num));
        memset(dp,0,sizeof(dp));
        for(i=0;i<n;i++)
        {
            a[i] = s[i] - '0';
            num[a[i]]++;
        }
        dp[0][0] = 1;
        for(i=0;i<(1<<n);i++)
        {
            for(j=0;j<n;j++)
            {
                if(i&(1<<j))
                    continue;
                for(k=0;k<d;k++)
                {
                    if(dp[i][k]==0)
                        continue;
                    dp[i|(1<<j)][(k*10+a[j])%d]+=dp[i][k];
                }
            }
        }
        int ans = dp[(1<<n)-1][0];
        for(i=0;i<10;i++)
            ans /= f[num[i]];
        printf("Case %d: %d\n",cas++,ans);
    }

    return 0;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值