class Solution {
private static final long[] fact = new long[] { 1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800 };
Set<String> duplicate = new HashSet<>();
public long countGoodIntegers(int n, int k) {
long min = (long) Math.pow(10, (n - 1) / 2);
long max = min * 10 - 1;
long count = 0;
for (long i = min; i <= max; i++) {
long parlin = toParlind(i, n);
if (parlin % k == 0) {
count += countRearrange(parlin, n);
}
}
return count;
}
private long countRearrange(long num, int n) {
String s = Long.toString(num);
int[] count = new int[10];
for (int i = 0; i < s.length(); i++) {
count[s.charAt(i) - '0']++;
}
StringBuilder sb = new StringBuilder();
for(int i = 0; i < 10; i++) {
sb.append(i).append(count[i]);
}
if (duplicate.contains(sb.toString())) {
return 0;
}
duplicate.add(sb.toString());
long sub = fact[n];
for (int i = 0; i < 10; i++) {
if (count[i] > 1) {
sub /= fact[count[i]];
}
}
if (count[0] > 0) {
count[0]--;
long sub2 = fact[n - 1];
for (int i = 0; i < 10; i++) {
if (count[i] > 1) {
sub2 /= fact[count[i]];
}
}
sub -= sub2;
}
return sub;
}
private long toParlind(long num, int n) {
long temp = num;
if (n % 2 == 1)
temp /= 10;
while (temp > 0) {
num = num * 10 + temp % 10;
temp /= 10;
}
return num;
}
}