Topic Link:
Http://codeforces.com/problemset/problem/401/D
D. Roman and Numbers time limit/test 4 seconds memory limit per test megabytes input standard input output Standar D Output
Roman is a young mathematician, very famous in Uzhland. Unfortunately, Sereja doesn ' t. To make Sereja the change he mind, Roman is ready to solve any mathematical problem. After some thought, Sereja asked Roma to find, how many numbers the close to number N, are M.
Number x is considered close to number n modulo m, if:it can being obtained by rearranging the digits of number n, it doesn ' t have any leading zeroes, the remainder over dividing number x by M equals 0.
Roman is a good mathematician, but the number of such numbers are too huge for him. So he asks the him.
Input
The contains two integers:n (1≤n < 1018) and M (1≤m≤100). Output
In a single line print a single integer-the number of numbers close to number n modulo M. Sample test (s) input
104 2
Output
3
Input
223 4
Output
1
Input
7067678 8
Output
47
Note
In the the required numbers are:104, 140, 410.
The second sample the required number is 232.
topic Meaning:
Give an n (n<=10^18), M (m<=100), to the number of numbers that can be divided by M (not 0) by the number of rows in N.
Ideas for solving problems:
Digital DP
Dp[s][m] means that when the remaining number consists of the state of S, the number of digits used consists of M, the number of species that satisfies the requirement can be formed.
Each of the remaining number of enumeration, remove it. Note that each digit may have the same number, and only one is required.
Code:
#include <CSpreadSheet.h> #include <iostream> #include <cmath> #include <cstdio> #include <sstream> #include <cstdlib> #include <string> #include <string.h> #include <cstring> # include<algorithm> #include <vector> #include <map> #include <set> #include <stack> # include<list> #include <queue> #include <ctime> #include <bitset> #include <cmath> # Define EPS 1e-6 #define INF 0x3f3f3f3f #define PI acos ( -1.0) #define LL __int64 #define LL long #define Lson l,m, (rt& lt;<1) #define Rson m+1,r, (rt<<1) |1 #define m 1000000007//#pragma comment (linker, "/stack
: 1024000000,1024000000 ") using namespace std; ll dp[1<<19][101];
DP[S][M] Indicates that there is still a number of States with S, and the preceding remainder is m, the number of required numbers is met//This avoids the repetition of the previous remainder of M n,m;
int cnt,va[20];
void Init (ll cur) {cnt=0;
while (cur) {va[cnt++]=cur%10;
cur/=10;
} ll Dfs (ll cur,ll fi) {if (!cur)//Every bit has all been done {if (!FI) return 1;
return 0;
if (dp[cur][fi]!=-1)//previously sought, now do not require return DP[CUR][FI];
int num[10];
memset (num,0,sizeof (num));
ll Res=0;
for (int i=0;i<cnt;i++) {if (cur& (1<<i))//I number is still inside {if (Num[va[i]])
Continue
Num[va[i]]=1; Res+=dfs (cur^ (1<<i), (fi*10+va[i))%m); Put the number I in} return dp[cur][fi]=res;
Save} int Main () {//printf ("%d\n", 1<<18);
Freopen ("In.txt", "R", stdin);
Freopen ("OUT.txt", "w", stdout);
while (~SCANF ("%i64d%i64d", &n,&m)) {init (n);
Memset (Dp,-1,sizeof (DP));
int num[10];
memset (num,0,sizeof (num));
int lim= (1<<CNT)-1;
ll Ans=0; for (int i=0;i<cnt;i++) {if (num[va[i]]| |!
Va[i]//Note that the first is not zero continue;
Num[va[i]]=1;
Ans+=dfs (lim^ (1<<i), va[i]%m); printf ("%i64d\N ", ans);
return 0;
}