1021 - Painful Bases

  PDF (English) Statistics Forum
Time Limit: 2 second(s) Memory Limit: 32 MB

As you know that sometimes base conversion is a painful task. But still there are interesting facts in bases.

For convenience let‘s assume that we are dealing with the bases from 2 to 16. The valid symbols are 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E and F. And you can assume that all the numbers given in this problem are valid. For example 67AB is not a valid number of base 11, since the allowed digits for base 11 are 0 to A.

Now in this problem you are given a base, an integer K and a valid number in the base which contains distinct digits. You have to find the number of permutations of the given number which are divisible by K. K is given in decimal.

For this problem, you can assume that numbers with leading zeroes are allowed. So, 096 is a valid integer.

Input

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

Each case starts with a blank line. After that there will be two integers, base (2 ≤ base ≤ 16) and K (1 ≤ K ≤ 20). The next line contains a valid integer in that base which contains distinct digits, that means in that number no digit occurs more than once.

Output

For each case, print the case number and the desired result.

Sample Input

Output for Sample Input


3

2 2

10

10 2

5681

16 1

ABCDEF0123456789


Case 1: 1

Case 2: 12

Case 3: 20922789888000

题意:给你的n为进制,后面的m为模数,然后给你一串数字为当前进制下的数,问你拆分这个数,然后再全排列组成新的数,问这些数中有多少是m的倍数;

思路:状态压缩dp;

dp[i][j]表示在i状态下对m取模为j的种数;我们可以将这些数组合,那么种数就是2n,然后每一种组合就是一种状态,那么每种状态下可能的模数有m-1种,那么咋实现全排列,

全排列就是组合数承n!;那么每种状态可以由前面的状态推来那么这就是全排列的过程,只不过将相同的合并。

状态转移方程看下面代码:

 1 #include<stdio.h>
 2 #include<algorithm>
 3 #include<iostream>
 4 #include<string.h>
 5 #include<stdlib.h>
 6 #include<math.h>
 7 #include<queue>
 8 #include<stack>
 9 #include<vector>
10 using namespace std;
11 typedef long long LL;
12 char ans[100];
13 int shu[100];
14 LL  dp[1<<16+1][22];
15 int main(void)
16 {
17         int i,j,k;
18         scanf("%d",&k);
19         int s;
20         for(s=1; s<=k; s++)
21         {
22                 int n,m;
23                 scanf("%d %d",&n,&m);
24                 scanf("%s",ans);
25                 int l=strlen(ans);
26                 for(i=0; i<l; i++)
27                 {
28                         if(ans[i]>=‘0‘&&ans[i]<=‘9‘)
29                         {
30                                 shu[i]=ans[i]-‘0‘;
31                         }
32                         else
33                         {
34                                 shu[i]=ans[i]-‘A‘+10;
35                         }
36                 }
37                 memset(dp,0,sizeof(dp));
38                 dp[0][0]=1;
39                 for(i=0; i<(1<<l); i++)
40                 {
41                         for(j=0; j<=m-1; j++)
42                         {
43                                 for(int s=0; s<l; s++)
44                                 {
45                                         int ak=j;
46                                         if(!(i&(1<<s)))
47                                         {
48                                                 dp[i|(1<<s)][(ak*n+shu[s])%m]+=dp[i][j];
49                                         }
50                                 }
51                         }
52                 }
53                 printf("Case %d: %lld\n",s,dp[(1<<l)-1][0]);
54         }
55         return 0;
56 }
时间: 2025-01-07 21:20:04

1021 - Painful Bases的相关文章

lightoj 1021 - Painful Bases(数位dp+状压)

题目链接:http://www.lightoj.com/volume_showproblem.php?problem=1021 题解:简单的数位dp由于总共就只有16个存储一下状态就行了. #include <iostream> #include <cstring> #include <cstdio> #include <cmath> using namespace std; typedef long long ll; ll dp[1 << 17

Light oj 1021 - Painful Bases

题意:  给一个B进制的数,一个10进制的数K,B进制数有x位, 对着x位进行全排列的话,有x!种可能, 问这x!的可能中,有多少种可以整除K,各个位置上的数字都不同. 思路:状态压缩,数位DP #include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<vector> #include<set&

lightoj-1021 - Painful Bases(状压+数位dp)

1021 - Painful Bases PDF (English) Statistics ForumTime Limit: 2 second(s) Memory Limit: 32 MBAs you know that sometimes base conversion is a painful task. But still there are interesting facts in bases. For convenience let's assume that we are deali

LightOJ1021 Painful Bases(状压DP)

容易想到状态dp[n][S][m](S是数字出现的集合),表示前n位用了数字集S且模k余数是m的方案数. 利用 (xy)base % k = ( x*base+y ) % k = (( x%k ) * base + y) % k ,进行状态第三维的转移. 不过d[16][216][20]有2000多W的状态数,且不说超时的问题,内存早已超过限制了. 可以发现,S这一维其实就包含了n这一维的信息了,所以只要二维就能表示状态. dp[m][S]表示,数字集为s且模k余数为m的方案数 状态的转移,从前

LightOJ1021---Painful Bases (状压dp)

As you know that sometimes base conversion is a painful task. But still there are interesting facts in bases. For convenience let's assume that we are dealing with the bases from 2 to 16. The valid symbols are 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D

1021. Deepest Root (25) 并查集&amp;&amp;DFS

1021. Deepest Root (25) 时间限制 1500 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Yue A graph which is connected and acyclic can be considered a tree. The height of the tree depends on the selected root. Now you are supposed to find the root t

HDU 1021[Fibonacci Again]规律

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1021 题目大意:首两项为7,11的斐波那契数列.若第n项能被3整除,输出yes,否则输出no 关键思想:模三加法情况有限,找规律. 代码如下: #include <iostream> using namespace std; int main(){ int n; while(cin>>n) if(n%8==2||n%8==6)cout<<"yes"<

BZOJ 1021: [SHOI2008]Debt 循环的债务( dp )

dp(i, j, k)表示考虑了前i种钱币(从小到大), Alice的钱数为j, Bob的钱数为k, 最小次数. 脑补一下可以发现, 只有A->B.C, B->A.C, C->A.B, A.B->C, A.C->B, B.C->A 6情况, 枚举然后dp一下就OK了. dp用刷表的话,有个强有力的剪枝是之后的硬币无论如何组合都无法满足时不去更新. --------------------------------------------------------------

【BZOJ】【1021】【SHOI2008】Dept循环的债务

DP 去膜拜题解了>_>玛雅原来是动规…… 让我先理解一下为什么要用动规:这个题根据钱数推方案其实是无从下手的……(线性规划?……事实证明我想多了) 啦-我们先来看个超级简化版的问题:怎么判无法还清?正着判很麻烦对不对= =(其实是我没想……) 那么我们倒着来考虑:有哪些状态是我们通过交换钱币能够到达的,这个可以递推对不>_> 现在我们就知道哪些状态我们是可以到达的了……再多想一下……递推……如果我们依次考虑每种面额的交换策略,顺便也就知道了我们到达这个状态的最小交换次数对吧? 原